当前位置:  开发笔记 > 编程语言 > 正文

MySQL - 具有一个变量变化的SAME查询需要更长时间的10倍

如何解决《MySQL-具有一个变量变化的SAME查询需要更长时间的10倍》经验,为你挑选了1个好方法。

我有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



1> Rick James..:

该配置文件为您提供了答案 - 查询缓存.

从只有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

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有