我有MySQL DB,我总是问同样的"问题",我改变的只是查询中的VIN变量.
更具体地说,我向你展示了2个查询:第一个有VIN:(U5YFF24128L064909
需要0.0002秒)
SELECT c.vin, c.case_id, c.claimnumber, c.platenumber, c.axrmrs_id, c.insurer_memberid, c.country, c.date_created, c.totalloss, c.lastcalc_manufacturer_code, c.lastcalc_model_code, c.lastcalc_submodel_code, c.audavin_triggered, c.accident_date, c.registration_date, c.manufacturing_year, cl.spareparts, cl.totalcosts, cl.laborhours, cl.laborcosts, cl.calculationdate, cl.paintlabor, cl.paintmaterial, cl.currency, car.manufacturer, car.model, car.submodel, IFNULL(org.name, 0) as orgName, GROUP_CONCAT(DISTINCT IF(po.repairmethod LIKE 'L%', po.text,NULL) ORDER BY 1) AS textL, GROUP_CONCAT(DISTINCT IF(po.repairmethod = 'E', po.text,NULL ) ORDER BY 1) AS textE , GROUP_CONCAT(DISTINCT IF(po.repairmethod != 'E' OR (po.repairmethod = 'E' AND po.guidenumber = 'N/A' ) AND po.repairmethod NOT LIKE 'L%',po.text, NULL ) ORDER BY 1 ) AS textO FROM axnmrs_cases AS c LEFT JOIN axnmrs_calculations as cl on c.case_id = cl.case_id AND c.country = cl.country LEFT JOIN axnmrs_positions as po on c.case_id = po.case_id LEFT JOIN car_type as car on car.manufacturer_code = c.lastcalc_manufacturer_code AND car.main_type = c.lastcalc_model_code AND car.subtype_code = c.lastcalc_submodel_code LEFT JOIN organization_list as org on org.memberId = c.insurer_memberid WHERE c.vin= 'U5YFF24128L064909' GROUP BY c.vin, c.case_id, c.axrmrs_id
和第二个VIN = VF38BRHZE80728805
(这需要2.4387秒)
SELECT c.vin, c.case_id, c.claimnumber, c.platenumber, c.axrmrs_id, c.insurer_memberid, c.country, c.date_created, c.totalloss, c.lastcalc_manufacturer_code, c.lastcalc_model_code, c.lastcalc_submodel_code, c.audavin_triggered, c.accident_date, c.registration_date, c.manufacturing_year, cl.spareparts, cl.totalcosts, cl.laborhours, cl.laborcosts, cl.calculationdate, cl.paintlabor, cl.paintmaterial, cl.currency, car.manufacturer, car.model, car.submodel, IFNULL(org.name, 0) as orgName, GROUP_CONCAT(DISTINCT IF(po.repairmethod LIKE 'L%', po.text,NULL) ORDER BY 1) AS textL, GROUP_CONCAT(DISTINCT IF(po.repairmethod = 'E', po.text,NULL ) ORDER BY 1) AS textE , GROUP_CONCAT(DISTINCT IF(po.repairmethod != 'E' OR (po.repairmethod = 'E' AND po.guidenumber = 'N/A' ) AND po.repairmethod NOT LIKE 'L%',po.text, NULL ) ORDER BY 1 ) AS textO FROM axnmrs_cases AS c LEFT JOIN axnmrs_calculations as cl on c.case_id = cl.case_id AND c.country = cl.country LEFT JOIN axnmrs_positions as po on c.case_id = po.case_id LEFT JOIN car_type as car on car.manufacturer_code = c.lastcalc_manufacturer_code AND car.main_type = c.lastcalc_model_code AND car.subtype_code = c.lastcalc_submodel_code LEFT JOIN organization_list as org on org.memberId = c.insurer_memberid WHERE c.vin= 'VF38BRHZE80728805' GROUP BY c.vin, c.case_id, c.axrmrs_id
我不知道为什么会发生这种情况所以我尝试分析所以我在PHPMYADMIN中使用"PROFILE"函数,它在屏幕上返回如下结果:VIN: U5YFF24128L064909
和VIN :( VF38BRHZE80728805
显然操作时间更长)
因为我不能谷歌任何有用的东西我也尝试EXPLAIN SELECT查询,如下所示:对于VIN: U5YFF24128L064909
而对于VIN: VF38BRHZE80728805
从这个解释我认为我在car_type表上做了很好的查询应该写得更好,但是它不会改变同一查询的速度只是用不同的VIN号.
我也在想我的第一个QUERY刚从CACHE返回,第二个来自DB.所以我尝试再次进行两次查询.而且两者都和以前一样.
有谁能帮我找到这个查询的问题吗?我做错了什么?
感谢您的任何建议,因为我已经迷失了!
编辑:在car_type
表我对指标:manufacturer_code
,main_type
,subtype_code
编辑2:要深入分析我尝试SHOW CREATE TABLE {{table name}},结果如下.
axnmrs_cases:
CREATE TABLE `axnmrs_cases` ( `axrmrs_id` int(11) NOT NULL DEFAULT '0', `case_id` int(11) NOT NULL DEFAULT '0', `axncase_guid` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `date_created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `datasource` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `claimnumber` varchar(60) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `platenumber` varchar(60) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `displayname` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `vin` varchar(40) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `lastcalc_manufacturer_code` varchar(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `lastcalc_model_code` varchar(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `lastcalc_submodel_code` varchar(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `lastcalc_model_options` varchar(500) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `audavin_triggered` varchar(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `vehicletype` varchar(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `accident_date` timestamp NULL DEFAULT '0000-00-00 00:00:00', `date_closed` timestamp NULL DEFAULT '0000-00-00 00:00:00', `claimowner_memberid` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `repairer_memberid` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `insurer_memberid` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `assessor_memberid` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `accidentcause_code` int(11) DEFAULT NULL, `casetype_code` int(11) DEFAULT NULL, `claimtype_code` int(11) DEFAULT NULL, `damagecause_code` int(11) DEFAULT NULL, `damagearea_codes` varchar(20) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `totalloss` varchar(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `inspectionrequired` varchar(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `manufacturing_year` int(11) NOT NULL DEFAULT '0', `registration_date` timestamp NULL DEFAULT '0000-00-00 00:00:00', `mileage` int(11) NOT NULL DEFAULT '0', `country` varchar(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `id` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`), KEY `VIN_index` (`vin`) ) ENGINE=InnoDB AUTO_INCREMENT=3471525 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
axnmrs_calculations:
CREATE TABLE `axnmrs_calculations` ( `calculation_id` int(11) NOT NULL, `case_id` int(11) NOT NULL, `guid` varchar(50) NOT NULL, `calculationdate` varchar(50) NOT NULL, `name` varchar(50) NOT NULL, `calsscalnr` varchar(50) NOT NULL, `model_options` varchar(60) NOT NULL, `spareparts` varchar(60) NOT NULL, `laborcosts` varchar(60) NOT NULL, `paintlabor` varchar(60) NOT NULL, `paintmaterial` varchar(40) NOT NULL, `extracosts` varchar(60) NOT NULL, `environmentalcosts` varchar(60) NOT NULL, `totalcosts` varchar(60) NOT NULL, `totalvat` varchar(60) NOT NULL, `laborhours` varchar(60) NOT NULL, `painthours` varchar(60) NOT NULL, `totaldeduction` varchar(60) NOT NULL, `partsadjustment` varchar(60) NOT NULL, `calculationtype` varchar(60) NOT NULL, `license` varchar(60) NOT NULL, `memberrole` varchar(60) NOT NULL, `currency` varchar(5) NOT NULL, `country` varchar(2) NOT NULL, KEY `caseid_index` (`case_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1
axnmrs_positions:
CREATE TABLE `axnmrs_positions` ( `calculation_id` int(11) NOT NULL DEFAULT '0', `case_id` int(11) NOT NULL DEFAULT '0', `position_id` int(11) NOT NULL DEFAULT '0', `blockline` varchar(7) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `repairmethod` varchar(3) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `guidenumber` varchar(4) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `amount` float NOT NULL DEFAULT '0', `hours` float NOT NULL DEFAULT '0', `starmutation` varchar(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `text` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `originalpartnumber` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `originalpartprice` float NOT NULL DEFAULT '0', `manufacturercode` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `quality` varchar(5) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', `suppliercode` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0', KEY `calculationid_index` (`calculation_id`), KEY `repairmethod` (`repairmethod`), KEY `caseid_index` (`case_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
car_type:
CREATE TABLE `car_type` ( `manufacturer_code` varchar(2) NOT NULL, `main_type` varchar(2) NOT NULL, `subtype_code` varchar(2) NOT NULL, `manufacturer` varchar(100) NOT NULL, `model` varchar(20) CHARACTER SET utf8 COLLATE utf8_czech_ci NOT NULL, `submodel` varchar(20) CHARACTER SET utf8 COLLATE utf8_czech_ci NOT NULL, KEY `manufacturer_code` (`manufacturer_code`), KEY `main_type` (`main_type`), KEY `subtype_code` (`subtype_code`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1
organization_list:
CREATE TABLE `organization_list` ( `id` int(11) NOT NULL AUTO_INCREMENT, `memberId` varchar(99) NOT NULL, `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_czech_ci NOT NULL, PRIMARY KEY (`id`), KEY `memberId` (`memberId`) ) ENGINE=InnoDB AUTO_INCREMENT=133 DEFAULT CHARSET=latin1
Rick James.. 5
该配置文件为您提供了答案 - 查询缓存.
从只有0.2的查询中获取结果的唯一方法是它来自"查询缓存".这是选择结果集的哈希.你显然运行了两次查询,这是第二次计时.再试一次,SELECT SQL_NO_CACHE ...
看看它"真正"需要多长时间.
请注意,"查询缓存"不是MySQL使用的唯一"缓存"; 所以在使用术语时要小心.
(那不是10倍;那要长10000倍.)
除此之外,你的下一个问题是为什么这样的查询需要2.4秒? 这是你应该解决的问题.线索在EXPLAIN
- 首先注意到巨大的"行" car
.
LEFT JOIN car_type as car on car.manufacturer_code = c.lastcalc_manufacturer_code AND car.main_type = c.lastcalc_model_code AND car.subtype_code = c.lastcalc_submodel_code
添加此复合索引car_type
将加速查询的该部分.
INDEX(manufacturer_code, main_type, subtype_code)
(在这种情况下,顺序无关紧要.)
也,
LEFT JOIN organization_list as org on org.memberId = c.insurer_memberid
需要一个一致的memberId定义.仔细看看CHARACTER SET
两张表中的内容.
使用ALTER TABLE ... CONVERT TO ...
来解决这个问题,以便它可以使用索引.
另见Index Cookbook
该配置文件为您提供了答案 - 查询缓存.
从只有0.2的查询中获取结果的唯一方法是它来自"查询缓存".这是选择结果集的哈希.你显然运行了两次查询,这是第二次计时.再试一次,SELECT SQL_NO_CACHE ...
看看它"真正"需要多长时间.
请注意,"查询缓存"不是MySQL使用的唯一"缓存"; 所以在使用术语时要小心.
(那不是10倍;那要长10000倍.)
除此之外,你的下一个问题是为什么这样的查询需要2.4秒? 这是你应该解决的问题.线索在EXPLAIN
- 首先注意到巨大的"行" car
.
LEFT JOIN car_type as car on car.manufacturer_code = c.lastcalc_manufacturer_code AND car.main_type = c.lastcalc_model_code AND car.subtype_code = c.lastcalc_submodel_code
添加此复合索引car_type
将加速查询的该部分.
INDEX(manufacturer_code, main_type, subtype_code)
(在这种情况下,顺序无关紧要.)
也,
LEFT JOIN organization_list as org on org.memberId = c.insurer_memberid
需要一个一致的memberId定义.仔细看看CHARACTER SET
两张表中的内容.
使用ALTER TABLE ... CONVERT TO ...
来解决这个问题,以便它可以使用索引.
另见Index Cookbook