我有 MySQL 数据库,我总是问同样的“问题”,我唯一改变的是查询中的 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”函数,它在屏幕上返回如下结果:
车牌号:U5YFF24128L064909
和 VIN:VF38BRHZE80728805
(显然是更长的操作)
因为我无法从中搜索到任何有用的信息,所以我也尝试了如下所示的 EXPLAIN SELECT 查询:
对于 VIN:U5YFF24128L064909
根据这个解释,我认为我在 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
汽车类型:
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
组织列表:
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
最佳答案
配置文件为您提供了答案——查询缓存。
从 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 ...
解决此问题,以便它可以使用索引。
关于MySQL - 具有一个变量更改的 SAME 查询花费的时间超过 10 倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34679256/