我的查询执行缓慢(约20秒),经过大量阅读和挖掘后,我似乎无法找到解决方案。
查询是:
EXPLAIN EXTENDED
SELECT t1.*
FROM tire_transaction AS t1
INNER JOIN (SELECT license_plate,
Max(transaction_date) AS `last_checkin`
FROM tire_transaction
GROUP BY license_plate) AS t2
ON t1.license_plate = t2.license_plate
AND t1.transaction_date = t2.last_checkin
WHERE ( t1.client_id = '1' )
AND ( t1.deleted = 0 )
结果是:
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL (NULL) (NULL) (NULL) (NULL) 69121 100.00
1 PRIMARY t1 ref client_id,license_plate,tire_transaction_date,deleted,license__trans_date license__trans_date 67 t2.last_checkin,t2.license_plate 1 100.00 Using where
2 DERIVED tire_transaction index (NULL) license_plate 63 (NULL) 366423 100.00
表格是:
CREATE TABLE `tire_transaction` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`entity_id` int(11) DEFAULT NULL,
`client_id` int(11) NOT NULL,
`company_id` int(11) NOT NULL,
`parent_id` int(11) DEFAULT NULL,
`transaction_type` tinyint(1) DEFAULT '0',
`transaction_date` date DEFAULT NULL,
`transaction_status` int(11) DEFAULT NULL,
`transaction_urgent` tinyint(1) NOT NULL DEFAULT '0',
`license_plate` varchar(20) DEFAULT NULL,
`license_plate_country` varchar(2) DEFAULT 'NL',
`chassis_number` varchar(40) DEFAULT NULL,
`brand` varchar(255) DEFAULT NULL,
`brand_type` varchar(255) DEFAULT NULL,
`client_name` varchar(255) DEFAULT NULL,
`client_salutation` varchar(255) DEFAULT NULL,
`client_company` varchar(255) DEFAULT NULL,
`client_street` varchar(255) DEFAULT NULL,
`client_number` varchar(255) DEFAULT NULL,
`client_postalcode` varchar(255) DEFAULT NULL,
`client_city` varchar(255) DEFAULT NULL,
`client_phone` varchar(255) DEFAULT NULL,
`client_phone_alt` varchar(255) DEFAULT NULL,
`client_email` varchar(255) DEFAULT NULL,
`tire_type` tinyint(1) DEFAULT '0',
`set_price` int(11) DEFAULT NULL,
`rim_material` tinyint(1) DEFAULT '0',
`notes` text,
`created` datetime DEFAULT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `client_id` (`client_id`) USING BTREE,
KEY `company_id` (`company_id`) USING BTREE,
KEY `license_plate` (`license_plate`) USING BTREE,
KEY `client_name` (`client_name`) USING BTREE,
KEY `tire_transaction_entityId` (`entity_id`) USING BTREE,
KEY `tire_transaction_parentId` (`parent_id`) USING BTREE,
KEY `tire_transaction_date` (`transaction_date`),
KEY `deleted` (`deleted`),
KEY `license__trans_date` (`transaction_date`,`license_plate`)
) ENGINE=InnoDB AUTO_INCREMENT=418618 DEFAULT CHARSET=utf8
有400K行。 Mysql正在优化查询并将ON语句重写为WHERE语句,我认为这是缓慢的来源。
对此有什么看法?谢谢!
答案 0 :(得分:0)
将过滤器添加到子查询中。我不确定这是否会返回相同的结果。但是根据列名称,看起来应该是这样。
SELECT t1.*
FROM tire_transaction AS t1
INNER JOIN (SELECT license_plate,
Max(transaction_date) AS `last_checkin`
FROM tire_transaction
WHERE ( t1.client_id = '1' ) -- line added
AND ( t1.deleted = 0 ) -- line added
GROUP BY license_plate) AS t2
ON t1.license_plate = t2.license_plate
AND t1.transaction_date = t2.last_checkin
WHERE ( t1.client_id = '1' ) -- line can probably be deleted
AND ( t1.deleted = 0 ) -- line can probably be deleted
您还应该在(client_id, license_plate, transaction_date)
上添加索引。
答案 1 :(得分:0)
您可能能够提高性能的一个方面是子查询,它涉及GROUP BY
聚合(别名为t2
)。考虑在license_plate
和transaction_date
上添加综合索引:
CREATE INDEX tire_idx on tire_transaction(license_plate, transaction_date);
如果您在优化GROUP BY
查询时仔细阅读MySQL documentation,则上述索引应允许MySQL通过松散索引扫描进行聚合。如果上述情况有效,那么当您运行Using index for group-by
时,您应该会在Extra
列中看到EXPLAIN
。