最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

performance - Slow query wth left join, order by and "Copying to tmp table" - Stack Overflow

programmeradmin0浏览0评论

MariaDB – slow query with Copying to tmp table

This is my query:

SELECT 
vtiger_assets.asset_no, 
vtiger_assets.assetstatus,
vtiger_crmentity_user_field.starred 
FROM vtiger_assets  
INNER JOIN vtiger_crmentity ON vtiger_assets.assetsid = vtiger_crmentity.crmid 
LEFT JOIN vtiger_crmentity_user_field ON vtiger_assets.assetsid = vtiger_crmentity_user_field.recordid   
WHERE vtiger_crmentity.deleted=0 AND vtiger_assets.assetsid > 0 
ORDER BY vtiger_crmentity.modifiedtime DESC 
LIMIT 0, 35;

It performs about 30 sec

Explain shows possible key on vtiger_assets, key=primary, rows= 954878, extra=Using where; Using temporary; Using filesort Profiling shows the «Copying to tmp table» performs a long time

This fields vtiger_crmentity.modifiedtime, vtiger_assets.assetsid, vtiger_crmentity.crmid, vtiger_crmentity.deleted и vtiger_assets.assetsid have indexes.

If I exclude «ORDER BY vtiger_crmentity.modifiedtime DESC» the query performs quick, the explain shows possible key on vtiger_assets, key=primary, rows= 954878, extra=Using where;

If I return "order by" and exclude « LEFT JOIN vtiger_crmentity_user_field ON vtiger_assets.assetsid = vtiger_crmentity_user_field.recordid » the query also performs quick, the explain shows possible key on vtiger_assets, key=primary, rows= 70, extra=Using where;

The only problem I can see is the difference: vtiger_assets.assetsid is int(11) and vtiger_crmentity_user_field.recordid is int(19). But it seems to me, that the slow part is "order by". For some reason the index is not used with "left join". The query

select * from vtiger_crmentity vc order by modifiedtime desc limit 100

performs quick

The first query is generating by CRM, so I can’t change it in product environment.

All queries tested with big buffers like this:

SET SESSION join_buffer_size = 10*1024*1024*1024;
SET SESSION tmp_table_size = 10*1024*1024*1024;
SET SESSION max_heap_table_size = 10*1024*1024*1024;
SET SESSION sort_buffer_size= 10*1024*1024*1024;
SET SESSION read_rnd_buffer_size = 10*1024*1024;

Table definitions

CREATE TABLE `vtiger_assets` (
  `assetsid` int(11) NOT NULL,
  `asset_no` varchar(30) NOT NULL,
  `assetstatus` varchar(200) DEFAULT 'In Service',

…
  PRIMARY KEY (`assetsid`),
  UNIQUE KEY `vtiger_assets_UN` (`asset_no`),
  UNIQUE KEY `vtiger_assets_SN_UN` (`serialnumber`),
  KEY `vtiger_assets_product_IDX` (`product`) USING BTREE,
  CONSTRAINT `fk_1_vtiger_assets` FOREIGN KEY (`assetsid`) REFERENCES `vtiger_crmentity` (`crmid`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;


CREATE TABLE `vtiger_crmentity` (
  `crmid` int(19) NOT NULL,
  `modifiedtime` datetime NOT NULL,
  `deleted` int(1) NOT NULL DEFAULT '0',

…
  PRIMARY KEY (`crmid`),
  KEY `crmentity_smcreatorid_idx` (`smcreatorid`),
  KEY `crmentity_modifiedby_idx` (`modifiedby`),
  KEY `crmentity_deleted_idx` (`deleted`),
  KEY `crm_ownerid_del_setype_idx` (`smownerid`,`deleted`,`setype`),
  KEY `vtiger_crmentity_labelidx` (`label`),
  KEY `smownerid` (`smownerid`),
  KEY `vtiger_crmentity_modifiedtime_IDX` (`modifiedtime`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;


CREATE TABLE `vtiger_crmentity_user_field` (
  `recordid` int(19) NOT NULL,
  `userid` int(19) NOT NULL,
  `starred` varchar(100) DEFAULT NULL,
  KEY `record_user_idx` (`recordid`,`userid`),
  KEY `vtiger_crmentity_user_field_recordid_IDX` (`recordid`) USING BTREE,
  CONSTRAINT `fk_vtiger_crmentity_user_field_recordid` FOREIGN KEY (`recordid`) REFERENCES `vtiger_crmentity` (`crmid`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;

Explain

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE vtiger_assets range PRIMARY PRIMARY 4 955594 Using where; Using temporary; Using filesort
1 SIMPLE vtiger_crmentity eq_ref PRIMARY, crmentity_deleted_idx, vtiger_crmentity_deleted_IDX PRIMARY 4 spvtwp.vtiger_assets.assetsid 1 Using where
1 SIMPLE vtiger_crmentity_user_field ref record_user_idx, vtiger_crmentity_user_field_recordid_IDX record_user_idx 4 spvtwp.vtiger_assets.assetsid 1

MariaDB – slow query with Copying to tmp table

This is my query:

SELECT 
vtiger_assets.asset_no, 
vtiger_assets.assetstatus,
vtiger_crmentity_user_field.starred 
FROM vtiger_assets  
INNER JOIN vtiger_crmentity ON vtiger_assets.assetsid = vtiger_crmentity.crmid 
LEFT JOIN vtiger_crmentity_user_field ON vtiger_assets.assetsid = vtiger_crmentity_user_field.recordid   
WHERE vtiger_crmentity.deleted=0 AND vtiger_assets.assetsid > 0 
ORDER BY vtiger_crmentity.modifiedtime DESC 
LIMIT 0, 35;

It performs about 30 sec

Explain shows possible key on vtiger_assets, key=primary, rows= 954878, extra=Using where; Using temporary; Using filesort Profiling shows the «Copying to tmp table» performs a long time

This fields vtiger_crmentity.modifiedtime, vtiger_assets.assetsid, vtiger_crmentity.crmid, vtiger_crmentity.deleted и vtiger_assets.assetsid have indexes.

If I exclude «ORDER BY vtiger_crmentity.modifiedtime DESC» the query performs quick, the explain shows possible key on vtiger_assets, key=primary, rows= 954878, extra=Using where;

If I return "order by" and exclude « LEFT JOIN vtiger_crmentity_user_field ON vtiger_assets.assetsid = vtiger_crmentity_user_field.recordid » the query also performs quick, the explain shows possible key on vtiger_assets, key=primary, rows= 70, extra=Using where;

The only problem I can see is the difference: vtiger_assets.assetsid is int(11) and vtiger_crmentity_user_field.recordid is int(19). But it seems to me, that the slow part is "order by". For some reason the index is not used with "left join". The query

select * from vtiger_crmentity vc order by modifiedtime desc limit 100

performs quick

The first query is generating by CRM, so I can’t change it in product environment.

All queries tested with big buffers like this:

SET SESSION join_buffer_size = 10*1024*1024*1024;
SET SESSION tmp_table_size = 10*1024*1024*1024;
SET SESSION max_heap_table_size = 10*1024*1024*1024;
SET SESSION sort_buffer_size= 10*1024*1024*1024;
SET SESSION read_rnd_buffer_size = 10*1024*1024;

Table definitions

CREATE TABLE `vtiger_assets` (
  `assetsid` int(11) NOT NULL,
  `asset_no` varchar(30) NOT NULL,
  `assetstatus` varchar(200) DEFAULT 'In Service',

…
  PRIMARY KEY (`assetsid`),
  UNIQUE KEY `vtiger_assets_UN` (`asset_no`),
  UNIQUE KEY `vtiger_assets_SN_UN` (`serialnumber`),
  KEY `vtiger_assets_product_IDX` (`product`) USING BTREE,
  CONSTRAINT `fk_1_vtiger_assets` FOREIGN KEY (`assetsid`) REFERENCES `vtiger_crmentity` (`crmid`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;


CREATE TABLE `vtiger_crmentity` (
  `crmid` int(19) NOT NULL,
  `modifiedtime` datetime NOT NULL,
  `deleted` int(1) NOT NULL DEFAULT '0',

…
  PRIMARY KEY (`crmid`),
  KEY `crmentity_smcreatorid_idx` (`smcreatorid`),
  KEY `crmentity_modifiedby_idx` (`modifiedby`),
  KEY `crmentity_deleted_idx` (`deleted`),
  KEY `crm_ownerid_del_setype_idx` (`smownerid`,`deleted`,`setype`),
  KEY `vtiger_crmentity_labelidx` (`label`),
  KEY `smownerid` (`smownerid`),
  KEY `vtiger_crmentity_modifiedtime_IDX` (`modifiedtime`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;


CREATE TABLE `vtiger_crmentity_user_field` (
  `recordid` int(19) NOT NULL,
  `userid` int(19) NOT NULL,
  `starred` varchar(100) DEFAULT NULL,
  KEY `record_user_idx` (`recordid`,`userid`),
  KEY `vtiger_crmentity_user_field_recordid_IDX` (`recordid`) USING BTREE,
  CONSTRAINT `fk_vtiger_crmentity_user_field_recordid` FOREIGN KEY (`recordid`) REFERENCES `vtiger_crmentity` (`crmid`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;

Explain

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE vtiger_assets range PRIMARY PRIMARY 4 955594 Using where; Using temporary; Using filesort
1 SIMPLE vtiger_crmentity eq_ref PRIMARY, crmentity_deleted_idx, vtiger_crmentity_deleted_IDX PRIMARY 4 spvtwp.vtiger_assets.assetsid 1 Using where
1 SIMPLE vtiger_crmentity_user_field ref record_user_idx, vtiger_crmentity_user_field_recordid_IDX record_user_idx 4 spvtwp.vtiger_assets.assetsid 1

Show table status

Table Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Collation Comment
vtiger_assets InnoDB 10 Compressed 1911188 93 178216960 0 71753728 4194304 2025-02-01 19:29:03.000 utf8_general_ci row_format=COMPRESSED
vtiger_crmentity InnoDB 10 Compressed 3398937 50 170352640 0 244023296 5242880 2025-02-07 18:39:00.000 utf8_general_ci row_format=COMPRESSED
vtiger_crmentity_user_field InnoDB 10 Compressed 3537506 19 70615040 0 75186176 3670016 2025-02-07 18:58:12.000 utf8_general_ci row_format=COMPRESSED
RAM=32G
innodb_buffer_pool_size = 16G
Data in InnoDB tables: 7G (Tables: 1335)

What can I do to improve the performance of the first query?

Share Improve this question edited Feb 9 at 9:22 Юрий Глущенко asked Feb 3 at 10:12 Юрий ГлущенкоЮрий Глущенко 311 silver badge4 bronze badges 4
  • Table definitions Do not skip columns which are used anywhere in your code (indices, FKs, query..) – Akina Commented Feb 3 at 11:18
  • It can either use the crmid index to optimizs the join, or the modifiedby index to optimize ORDER BY. But I don't think it's able to do both. – Barmar Commented Feb 3 at 17:58
  • How much RAM do you have? What is the value of innodb_buffer_pool_size? – Rick James Commented Feb 5 at 18:47
  • All information added – Юрий Глущенко Commented Feb 9 at 9:27
Add a comment  | 

1 Answer 1

Reset to default 0

Add this composite index to vtiger_crmentity:

INDEX(deleted, modifiedtime)

in place of KEY crmentity_deleted_idx (deleted)

All tables should have a PRIMARY KEY. It is unusual to have 3 Unique keys (including the PK) on a table. Are you sure they are all needed?

ROW_FORMAT=COMPRESSED may cost speed while saving not much disk space. How big are the tables? (SHOW TABLE STATUS) How much RAM do you have? What is the setting of innodb_buffer_pool_size?

10G for four of those settings is unreasonable; it wastes a lot of RAM and threatens swapping.

Add this 'covering' (and composite) index to vtiger_crmentity_user_field:

INDEX(recordid,  starred)

Since the WHERE clause filters on two different tables, it is unlikely to do much toward speeding up the query.

Please provide EXPLAIN SELECT after adding those indexes. Something else may show up.

I suspect there is "swapping" -- considering those huge settings you chose.

发布评论

评论列表(0)

  1. 暂无评论