在mysql中使用临时命令解释性能计划;使用文件排序;使用索引条件

4sup72z8  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(509)

我在网上阅读了各种博客和文档,但只是想知道如何优化查询。我无法决定是否要重写查询或添加索引以进行优化。
还添加了create表结构

  1. CREATE TABLE `dsr_table` (
  2. `DSR_VIA` CHAR(3) DEFAULT NULL,
  3. `DSR_PULLDATA_FLAG` CHAR(1) DEFAULT 'O',
  4. `DSR_BILLING_FLAG` CHAR(1) DEFAULT 'O',
  5. `WH_FLAG` CHAR(1) DEFAULT 'O',
  6. `ARCHIVE_FLAG` CHAR(1) NOT NULL DEFAULT 'O',
  7. `DSR_BOOKING_TYPE` INT(2) DEFAULT NULL,
  8. `DSR_BRANCH_CODE` CHAR(3) NOT NULL,
  9. `DSR_CNNO` CHAR(12) NOT NULL,
  10. `DSR_BOOKED_BY` CHAR(1) NOT NULL,
  11. `DSR_CUST_CODE` VARCHAR(7) NOT NULL,
  12. `DSR_CN_WEIGHT` DECIMAL(8,3) NOT NULL,
  13. `DSR_CN_TYPE` CHAR(3) NOT NULL,
  14. `DSR_DEST` CHAR(3) NOT NULL,
  15. `DSR_MODE` CHAR(2) NOT NULL,
  16. `DSR_NO_OF_PIECES` DECIMAL(3,0) NOT NULL,
  17. `DSR_DEST_PIN` DECIMAL(6,0) DEFAULT NULL,
  18. `DSR_BOOKING_DATE` DATE NOT NULL,
  19. `DSR_AMT` DECIMAL(10,2) DEFAULT NULL,
  20. `DSR_STATUS` CHAR(1) NOT NULL,
  21. `DSR_POD_RECD` CHAR(1) DEFAULT NULL,
  22. `DSR_TRANSMF_NO` VARCHAR(10) NOT NULL,
  23. `DSR_BOOKING_TIME` CHAR(8) NOT NULL,
  24. `DSR_DOX` CHAR(1) NOT NULL,
  25. `DSR_SERVICE_TAX` DECIMAL(4,2) DEFAULT NULL,
  26. `DSR_SPL_DISC` DECIMAL(10,2) DEFAULT NULL,
  27. `DSR_CONTENTS` VARCHAR(255) DEFAULT NULL,
  28. `DSR_REMARKS` VARCHAR(25) DEFAULT NULL,
  29. `DSR_VALUE` VARCHAR(20) DEFAULT NULL,
  30. `DSR_INVNO` VARCHAR(10) DEFAULT NULL,
  31. `DSR_INVDATE` DATE DEFAULT NULL,
  32. `MOD_DATE` DATE DEFAULT NULL,
  33. `OFFICE_TYPE` CHAR(2) DEFAULT NULL,
  34. `OFFICE_CODE` CHAR(3) DEFAULT NULL,
  35. `DSR_REFNO` VARCHAR(50) DEFAULT NULL,
  36. `MOD_TIME` DECIMAL(4,0) DEFAULT NULL,
  37. `NODEID` VARCHAR(20) DEFAULT NULL,
  38. `USERID` VARCHAR(7) DEFAULT NULL,
  39. `TRANS_STATUS` CHAR(1) DEFAULT NULL,
  40. `DSR_ACT_CUST_CODE` VARCHAR(11) DEFAULT NULL,
  41. `DSR_MOBILE` VARCHAR(25) DEFAULT NULL,
  42. `DSR_EMAIL` VARCHAR(50) DEFAULT NULL,
  43. `DSR_NDX_PAPER` CHAR(1) DEFAULT NULL,
  44. `DSR_PICKUP_TIME` DECIMAL(4,0) DEFAULT NULL,
  45. `DSR_VOL_WEIGHT` DECIMAL(8,3) DEFAULT NULL,
  46. `DSR_CAPTURED_WEIGHT` DECIMAL(8,3) DEFAULT NULL,
  47. `DSR_PRODUCT` CHAR(3) DEFAULT NULL,
  48. `DSR_TRANS_STATUS_XI` CHAR(1) DEFAULT 'A',
  49. `DSR_TRANS_ID` DECIMAL(10,0) DEFAULT NULL,
  50. `DSR_ID_TYPE` INT(2) DEFAULT NULL,
  51. `DSR_ID_NUM` VARCHAR(50) DEFAULT NULL,
  52. `DSR_WT_CAPTURED` INT(1) DEFAULT NULL,
  53. `DSR_PUP_FRCODE` VARCHAR(7) DEFAULT NULL,
  54. `DSR_TS_AMT` DECIMAL(10,2) DEFAULT NULL,
  55. `DSR_FSC_PER` DECIMAL(4,2) DEFAULT NULL,
  56. `DSR_RATE_ID` DECIMAL(8,0) DEFAULT NULL COMMENT 'Used to store RateID by which final rate is calculated',
  57. `RECORD_ENTRY_DATETIME` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  58. `Record_creation_date` DATETIME DEFAULT NULL,
  59. `Record_Arrival_date` DATETIME DEFAULT NULL,
  60. `DSR_CONSIGNEE_MOBILE` VARCHAR(11) DEFAULT NULL,
  61. `DSR_PREV_WEIGHT` DECIMAL(8,3) DEFAULT NULL,
  62. `DSR_PREV_AMT` DECIMAL(10,2) DEFAULT NULL,
  63. `DSR_GOR_REMARKS` VARCHAR(50) DEFAULT NULL,
  64. `DSR_GOR_VOL_WT` DECIMAL(8,3) DEFAULT NULL,
  65. PRIMARY KEY (`DSR_CNNO`),
  66. KEY `idx_bcd_cnno_bkdate` (`DSR_BRANCH_CODE`,`DSR_CNNO`,`DSR_BOOKING_DATE`),
  67. KEY `idx_dsr_bkdate` (`DSR_BOOKING_DATE`),
  68. KEY `idx_dsr_custcode` (`DSR_CUST_CODE`),
  69. KEY `idx_dsr_invoiceno` (`DSR_INVNO`),
  70. KEY `idx_dsr_mdate` (`MOD_DATE`),
  71. KEY `idx_dsr_bookdby_ccd_cnno` (`DSR_BOOKED_BY`,`DSR_CUST_CODE`,`DSR_CNNO`),
  72. KEY `idx_dsr_bkdby_ccd_bkd_stat` (`DSR_BOOKED_BY`,`DSR_CUST_CODE`,`DSR_BOOKING_DATE`,`DSR_STATUS`),
  73. KEY `idx_dsr_refno` (`DSR_REFNO`),
  74. KEY `idx_dsr_txi_stat_mdate` (`DSR_TRANS_STATUS_XI`,`DSR_STATUS`,`MOD_DATE`),
  75. KEY `idx_dsr_trans_id` (`DSR_TRANS_ID`),
  76. KEY `idx_dsr_inv_date` (`DSR_INVDATE`),
  77. KEY `IDX_Create_arr_date` (`Record_creation_date`,`Record_Arrival_date`)
  78. ) ENGINE=INNODB DEFAULT CHARSET=latin1

这是我试图执行的查询。请帮我解决这个问题。

  1. select ob.BRANCH_CITY orig_city,dstb.BRANCH_CITY dest_city,round(sum(CASE WHEN left(dsr_cnno, 1) IN ('V', 'E', 'X') THEN
  2. IFNULL(value, 0) ELSE 0 END),2) Premium,
  3. round(sum(CASE WHEN left(dsr_cnno, 1) NOT IN ('V', 'E', 'X') THEN IFNULL(value, 0) ELSE 0 END),2) Non_Premium
  4. from ( select DSR_BRANCH_CODE,dsr_cnno,DSR_AMT,
  5. ((dsr_amt) +((((dsr_amt)-ifnull((select max(ndsr_ins_amt) from ndx_dsr_table where ndsr_cnno=dsr_cnno ),0)-ifnull((select max(ndsr_serv_charge) from ndx_dsr_table where ndsr_cnno=dsr_cnno ),0) -ifnull((select sum(dr_extra_amt) from dsr_revenue where dr_cnno=dsr_cnno ),0))-(((dsr_amt)-ifnull((select max(ndsr_ins_amt) from ndx_dsr_table where ndsr_cnno=dsr_cnno ),0) -ifnull((select max(ndsr_serv_charge) from ndx_dsr_table where ndsr_cnno=dsr_cnno ),0)
  6. -ifnull((select sum(dr_extra_amt) from dsr_revenue where dr_cnno=dsr_cnno ),0) )*ifnull(((select fr_discount from fr_mas where fr_Code=dsr_cust_code)),0)/100)) *ifnull(((select (case when dsr_invdate <'2017-05-01' then ifnull(fr_fsc_per,0) else 30 end) from fr_mas where fr_code=dsr_cust_code limit 1)),0)/100)) as value, dsr_cust_code
  7. ,dsr_dest_pin from dsr_table d where dsr_booking_date BETWEEN '2017-05-01' AND '2017-06-30' AND LENGTH(dsr_cnno)=9
  8. AND DSR_BOOKED_BY ='F' AND dsr_status<>'R' AND dsr_cnno NOT LIKE 'J%' AND dsr_cnno NOT LIKE '@%'
  9. AND dsr_cnno NOT LIKE '576%' AND dsr_cnno NOT LIKE 'I3%' AND dsr_cnno NOT LIKE '7%'
  10. AND dsr_cnno NOT LIKE 'N%' and d.dsr_dest_pin>0) zz
  11. inner join fr_mas f on f.FR_CODE=zz.dsr_cust_code
  12. inner join branch_mas ob on ob.BRANCH_CODE=zz.dsr_branch_code and ob.BRANCH_LOC='L'
  13. inner join serv_dest_mas dm on dm.SERV_PIN=zz.dsr_dest_pin
  14. inner join branch_mas dstb on dstb.BRANCH_CODE=dm.SERV_BRANCH and dstb.BRANCH_LOC='L'
  15. where dstb.BRANCH_CITY in ('HYD','DEL','AMD','GGN','BLR','PNQ','MUM','CHE','CCU','NOD')
  16. and ob.BRANCH_CITY in('HYD','DEL','AMD','GGN','BLR','PNQ','MUM','CHE','CCU','NOD')
  17. group by orig_city,dest_city ;

这是我的计划:

  1. id select_type table type possible_keys key key_len ref rows Extra
  2. ------ ------------------ ------------- ------ ------------------------------------------------------------------ ------------------------ ------- ------------------------- --------- ---------------------------------------------------------------------
  3. 1 PRIMARY ob range PRIMARY,FK_BRM_CITYMAS FK_BRM_CITYMAS 4 (NULL) 10 Using index condition; Using where; Using temporary; Using filesort
  4. 1 PRIMARY <derived2> ref <auto_key2> <auto_key2> 3 billingdb.ob.BRANCH_CODE 319051 Using where
  5. 1 PRIMARY f eq_ref PRIMARY PRIMARY 9 zz.dsr_cust_code 1 Using index
  6. 1 PRIMARY dm ref PRIMARY,IDX_SDM_SERVPIN_STATUS1 IDX_SDM_SERVPIN_STATUS1 3 zz.dsr_dest_pin 2 Using index
  7. 1 PRIMARY dstb eq_ref PRIMARY,FK_BRM_CITYMAS PRIMARY 3 billingdb.dm.SERV_BRANCH 1 Using where
  8. 2 DERIVED d ref idx_dsr_bkdate,idx_dsr_bookdby_ccd_cnno,idx_dsr_bkdby_ccd_bkd_stat idx_dsr_bookdby_ccd_cnno 1 const 182365315 Using index condition; Using where
  9. 10 DEPENDENT SUBQUERY fr_mas eq_ref PRIMARY PRIMARY 9 billingdb.d.DSR_CUST_CODE 1 (NULL)
  10. 9 DEPENDENT SUBQUERY fr_mas eq_ref PRIMARY PRIMARY 9 billingdb.d.DSR_CUST_CODE 1 (NULL)
  11. 8 DEPENDENT SUBQUERY dsr_revenue ref PRIMARY PRIMARY 12 billingdb.d.DSR_CNNO 1 (NULL)
  12. 7 DEPENDENT SUBQUERY ndx_dsr_table eq_ref PRIMARY PRIMARY 12 billingdb.d.DSR_CNNO 1 (NULL)
  13. 6 DEPENDENT SUBQUERY ndx_dsr_table eq_ref PRIMARY PRIMARY 12 billingdb.d.DSR_CNNO 1 (NULL)
  14. 5 DEPENDENT SUBQUERY dsr_revenue ref PRIMARY PRIMARY 12 billingdb.d.DSR_CNNO 1 (NULL)
  15. 4 DEPENDENT SUBQUERY ndx_dsr_table eq_ref PRIMARY PRIMARY 12 billingdb.d.DSR_CNNO 1 (NULL)
  16. 3 DEPENDENT SUBQUERY ndx_dsr_table eq_ref PRIMARY PRIMARY 12 billingdb.d.DSR_CNNO 1 (NULL)

更新
我还尝试在索引上添加索引(dsr\u booked\u by、dsr\u booking\u date、dsr\u cnno、dsr\u status、dsr\u cnno、dsr\u dist\u pin、id),但没有成功。
服务器的ram大小为16gb,innodb缓冲池大小为12gb
这个查询花了将近8个小时,但最终没有结果
更新
适用于特定日期的查询:

  1. SELECT ob.BRANCH_CITY orig_city,
  2. (
  3. SELECT LEFT(branch_code,1)
  4. FROM branch_mas c,serv_dest_mas b
  5. WHERE c.branch_loc='L'
  6. AND LEFT(c.branch_code,1) IN ('K','H','C','B','M','A',
  7. 'P','N','S','L'
  8. )
  9. AND c.branch_code=b.serv_branch
  10. AND b.serv_pin=zz.dsr_dest_pin
  11. LIMIT 1
  12. ) dest_city,
  13. ROUND(SUM(CASE WHEN LEFT(dsr_cnno, 1) IN ('V', 'E', 'X')
  14. THEN IFNULL(VALUE,
  15. 0) ELSE 0 END),2) Premium,
  16. ROUND(SUM(CASE WHEN LEFT(dsr_cnno,
  17. 1) NOT IN ('V', 'E', 'X') THEN IFNULL(VALUE,
  18. 0) ELSE 0 END),2
  19. ) Non_Premium FROM
  20. (
  21. SELECT DSR_BRANCH_CODE,dsr_cnno,DSR_AMT,
  22. ((dsr_amt) +((((dsr_amt) -IFNULL( (
  23. SELECT MAX(ndsr_serv_charge)
  24. FROM ndx_dsr_table
  25. WHERE ndsr_cnno=dsr_cnno ),0) -IFNULL(
  26. (
  27. SELECT SUM(dr_extra_amt)
  28. FROM dsr_revenue
  29. WHERE dr_cnno=dsr_cnno ),0))-(((dsr_amt) -IFNULL(
  30. (
  31. SELECT MAX(ndsr_ins_amt)
  32. FROM ndx_dsr_table
  33. WHERE ndsr_cnno=dsr_cnno ),0
  34. ) -IFNULL(
  35. (
  36. SELECT MAX(ndsr_serv_charge)
  37. FROM ndx_dsr_table
  38. WHERE ndsr_cnno=dsr_cnno ),0
  39. ) -IFNULL(
  40. (
  41. SELECT SUM(dr_extra_amt)
  42. FROM dsr_revenue
  43. WHERE dr_cnno=dsr_cnno ),0)
  44. ) *IFNULL((
  45. (
  46. SELECT fr_discount
  47. FROM fr_mas
  48. WHERE fr_Code=dsr_cust_code)),0)/100)) *
  49. IFNULL(( (
  50. SELECT (CASE WHEN dsr_invdate <'2017-05-01'
  51. THEN IFNULL(fr_fsc_per,
  52. 0) ELSE 30 END )
  53. FROM fr_mas
  54. WHERE fr_code=dsr_cust_code
  55. LIMIT 1)),0)/100)
  56. ) AS VALUE, dsr_cust_code, dsr_dest_pin
  57. FROM dsr_table d
  58. WHERE dsr_booking_date = '2017-04-30'
  59. AND LENGTH(dsr_cnno)=9
  60. AND DSR_BOOKED_BY ='F'
  61. AND dsr_status<>'R'
  62. AND d.dsr_dest_pin>0
  63. ) zz
  64. INNER JOIN fr_mas f ON f.FR_CODE=zz.dsr_cust_code
  65. INNER JOIN branch_mas ob ON ob.BRANCH_CODE=zz.dsr_branch_code
  66. AND ob.BRANCH_LOC='L'
  67. WHERE ob.BRANCH_CITY IN('HYD','DEL','AMD','GGN','BLR','PNQ',
  68. 'MUM','CHE','CCU','NOD'
  69. )
  70. AND d.dsr_cnno = f.dsr_cnno

如果我们指定一个月,则上述代码不适用于日期范围:

  1. SELECT ob.BRANCH_CITY orig_city,
  2. (
  3. SELECT LEFT(branch_code,1)
  4. FROM branch_mas c,serv_dest_mas b
  5. WHERE c.branch_loc='L'
  6. AND LEFT(c.branch_code,1) IN ('K','H','C','B','M','A',
  7. 'P','N','S','L'
  8. )
  9. AND c.branch_code=b.serv_branch
  10. AND b.serv_pin=zz.dsr_dest_pin
  11. LIMIT 1
  12. ) dest_city,
  13. ROUND(SUM(CASE WHEN LEFT(dsr_cnno, 1) IN ('V', 'E', 'X')
  14. THEN IFNULL(VALUE,
  15. 0) ELSE 0 END),2) Premium,
  16. ROUND(SUM(CASE WHEN LEFT(dsr_cnno,
  17. 1) NOT IN ('V', 'E', 'X') THEN IFNULL(VALUE,
  18. 0) ELSE 0 END),2
  19. ) Non_Premium FROM
  20. (
  21. SELECT DSR_BRANCH_CODE,dsr_cnno,DSR_AMT,
  22. ((dsr_amt) +((((dsr_amt) -IFNULL( (
  23. SELECT MAX(ndsr_serv_charge)
  24. FROM ndx_dsr_table
  25. WHERE ndsr_cnno=dsr_cnno ),0) -IFNULL(
  26. (
  27. SELECT SUM(dr_extra_amt)
  28. FROM dsr_revenue
  29. WHERE dr_cnno=dsr_cnno ),0))-(((dsr_amt) -IFNULL(
  30. (
  31. SELECT MAX(ndsr_ins_amt)
  32. FROM ndx_dsr_table
  33. WHERE ndsr_cnno=dsr_cnno ),0
  34. ) -IFNULL(
  35. (
  36. SELECT MAX(ndsr_serv_charge)
  37. FROM ndx_dsr_table
  38. WHERE ndsr_cnno=dsr_cnno ),0
  39. ) -IFNULL(
  40. (
  41. SELECT SUM(dr_extra_amt)
  42. FROM dsr_revenue
  43. WHERE dr_cnno=dsr_cnno ),0)
  44. ) *IFNULL((
  45. (
  46. SELECT fr_discount
  47. FROM fr_mas
  48. WHERE fr_Code=dsr_cust_code)),0)/100)
  49. ) *IFNULL((
  50. (
  51. SELECT (CASE WHEN dsr_invdate <'2017-05-01'
  52. THEN IFNULL(fr_fsc_per,
  53. 0) ELSE 30 END )
  54. FROM fr_mas
  55. WHERE fr_code=dsr_cust_code
  56. LIMIT 1)),0)/100)
  57. ) AS VALUE, dsr_cust_code, dsr_dest_pin
  58. FROM dsr_table d
  59. WHERE dsr_booking_date = '2017-04-30'
  60. AND '2017-05-30'
  61. AND LENGTH(dsr_cnno)=9
  62. AND DSR_BOOKED_BY ='F'
  63. AND dsr_status<>'R'
  64. AND d.dsr_dest_pin>0
  65. ) zz
  66. INNER JOIN fr_mas f ON f.FR_CODE=zz.dsr_cust_code
  67. INNER JOIN branch_mas ob ON ob.BRANCH_CODE=zz.dsr_branch_code
  68. AND ob.BRANCH_LOC='L'
  69. WHERE ob.BRANCH_CITY IN('HYD','DEL','AMD','GGN','BLR','PNQ',
  70. 'MUM','CHE','CCU','NOD'
  71. )
  72. AND d.dsr_cnno = f.dsr_cnno
ubof19bj

ubof19bj1#

请提供 SHOW CREATE TABLE .
主过滤器似乎是

  1. where dsr_booking_date BETWEEN '2017-05-01' AND '2017-06-30'
  2. AND LENGTH(dsr_cnno)=9
  3. AND DSR_BOOKED_BY ='F'
  4. AND dsr_status<>'R'
  5. AND dsr_cnno NOT LIKE 'J%'
  6. AND dsr_cnno NOT LIKE '@%'
  7. AND dsr_cnno NOT LIKE '576%'
  8. AND dsr_cnno NOT LIKE 'I3%'
  9. AND dsr_cnno NOT LIKE '7%'
  10. AND dsr_cnno NOT LIKE 'N%'
  11. and d.dsr_dest_pin>0

可能唯一有用的索引是,按以下顺序:

  1. INDEX(DSR_BOOKED_BY, dsr_booking_date)

比如

  1. ifnull((select max(ndsr_ins_amt) from ndx_dsr_table where ndsr_cnno=dsr_cnno ),0)-
  2. ifnull((select max(ndsr_serv_charge) from ndx_dsr_table where ndsr_cnno=dsr_cnno ),0) -

应该一起做。考虑一下

  1. ifnull(mm.max_nia), 0) -
  2. ifnull(mm.max_nsc), 0) .
  3. ...
  4. LEFT JOIN ( SELECT max(ndsr_ins_amt) AS max_nia,
  5. max(ndsr_serv_charge) AS max_nsc
  6. from ndx_dsr_table
  7. ) AS mm ON ndsr_cnno=dsr_cnno

或者,如果需要,用该子查询构建一个临时表,然后左连接到它。
(由于您没有用表限定每一列,因此我无法更具体地说。)
你们是否有适合于各种类型的“综合”指数 JOINs ?
根据 EXPLAIN ,它正在扫描182m行 dsr_table . 因此,我上面的索引可能会有所帮助(如果您还没有类似的索引的话)
我不太愿意建议这么长的索引,但这可能会有帮助:

  1. INDEX(DSR_BOOKED_BY, dsr_booking_date, -- these first, in this order
  2. dsr_cnno, dsr_status, dsr_cnno, dsr_dist_pin, -- in any order
  3. id) -- (whatever the PK of the table is); last

第二次查询时出现错误问题

  1. WHERE dsr_booking_date = '2017-04-30'
  2. AND '2017-05-30'

也许你的意思是31天:

  1. WHERE dsr_booking_date BETWEEN '2017-04-30'
  2. AND '2017-05-30'

或者2天:

  1. WHERE dsr_booking_date IN ('2017-04-30', '2017-05-30')

你所拥有的是

  1. WHERE dsr_booking_date = '2017-04-30' -- test for one day
  2. AND true -- that's how '2017-05-30' is interpreted
展开查看全部

相关问题