我打算使用这个SQL SELECT创建一个视图,但是它的解释显示它使用临时和使用filesort。我无法弄清楚我需要什么指数才能解决这个问题。大多数情况下,我想知道它为什么使用filesort而不是使用索引进行排序。
表bn_ms_gt_generaltransaction有700万条记录
表bn_pd_mp_masterprofile有几百条记录
表bn_pd_sc_scheme也有几百条记录
以下是create table语句:
CREATE TABLE `bn_ms_gt_generaltransaction` ( `GNTRDATE` date NOT NULL, `GNTRNUMBER` decimal(10,0) NOT NULL, `GNTRSUBNUMBER` decimal(5,0) NOT NULL, `ORGACODE` varchar(20) NOT NULL, `LOCACODE` varchar(20) NOT NULL, `PRODCODE` varchar(20) DEFAULT NULL, `SCHEMCODE` varchar(20) DEFAULT NULL, `BKMSNUMBER` varchar(50) DEFAULT NULL, `TRANCODE` varchar(20) NOT NULL, `GNTRVALUEDAT` date NOT NULL, `GNTRDRCR` varchar(20) NOT NULL, `GLACCODE` varchar(50) NOT NULL, `CURRCODE` varchar(20) NOT NULL, `GNTRAMTFC` decimal(15,2) NOT NULL, `GNTRSTATUS` varchar(2) DEFAULT NULL, `TMODCODE` varchar(20) DEFAULT NULL, PRIMARY KEY (`ORGACODE`,`LOCACODE`,`GNTRDATE`,`GNTRNUMBER`,`GNTRSUBNUMBER`), KEY `CC10921796764` (`TMODCODE`), KEY `SQL0407170412326` (`TRANCODE`), KEY `SQL0407170412328` (`CURRCODE`), KEY `SQL0407170412329` (`ORGACODE`,`GLACCODE`), KEY `GNTRDRCR` (`GNTRDRCR`), KEY `GLACCODE` (`GLACCODE`), KEY `GT_ACC_NUM` (`PRODCODE`,`SCHEMCODE`,`BKMSNUMBER`), KEY `GT_PK` (`GNTRDATE`,`GNTRNUMBER`,`GNTRSUBNUMBER`), KEY `GT_EFFECTDATE` (`GNTREFFECTDAT`), KEY `GT_GL_CODE` (`ORGACODE`,`LOCACODE`,`CURRCODE`,`GLACCODE`), KEY `INDEX_GNTRDATE` (`GNTRDATE`), KEY `INDEX_GNTRVALUEDAT` (`GNTRVALUEDAT`), KEY `GT_VOUCHER` (`GNTRDATE`,`GNTRNUMBER`), KEY `REPORT_INDEX_2` (`PRODCODE`,`SCHEMCODE`,`BKMSNUMBER`,`GNTRDATE`,`TRANCODE`,`GLACCODE`,`GNTRSTATUS`,`SGT_REVERSALTAG`,`GNTRAMTFC`), KEY `INDEX_LRDL_GROUPBY` (`PRODCODE`,`SCHEMCODE`,`BKMSNUMBER`,`GNTRDATE`,`GNTRVALUEDAT`,`GNTREFFECTDAT`,`GNTRNUMBER`,`TRANCODE`,`TMODCODE`), KEY `INDEX_LRDL_GROUPBY_LOOSE` (`PRODCODE`,`SCHEMCODE`,`BKMSNUMBER`,`GNTRDATE`,`GNTRVALUEDAT`,`GNTREFFECTDAT`,`GNTRNUMBER`,`TRANCODE`,`TMODCODE`,`GNTRAMTFC`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `bn_pd_mp_masterprofile` ( `PRODCODE` varchar(20) NOT NULL, `ORGACODE` varchar(20) DEFAULT NULL, `GLACCODE` varchar(50) DEFAULT NULL, PRIMARY KEY (`PRODCODE`), KEY `SQL040126114206101` (`ORGACODE`,`GLACCODE`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `bn_pd_sc_scheme` ( `PRODCODE` varchar(20) NOT NULL, `SCHEMCODE` varchar(20) NOT NULL, `ORGACODE` varchar(20) DEFAULT NULL, `GLACCODE` varchar(50) DEFAULT NULL, `CURRCODE` varchar(20) DEFAULT NULL, `SCHEPURPOSE` varchar(100) DEFAULT NULL, `CODE_PENALTY` varchar(50) DEFAULT NULL, PRIMARY KEY (`PRODCODE`,`SCHEMCODE`), KEY `SQL040126114217543` (`CURRCODE`), KEY `CC1318422668625` (`PST_PSTYCODE`), KEY `SQL040126114217560` (`ORGACODE`,`GLACCODE`), KEY `CC1205848198000` (`ORGACODE`,`CODE_PENALTY`), CONSTRAINT `CC1205848198000` FOREIGN KEY (`ORGACODE`, `CODE_PENALTY`) REFERENCES `pr_gl_ca_account` (`ORGACODE`, `GLACCODE`), CONSTRAINT `SQL040126114217543` FOREIGN KEY (`CURRCODE`) REFERENCES `pr_gn_cr_currency` (`CURRCODE`), CONSTRAINT `SQL040126114217560` FOREIGN KEY (`ORGACODE`, `GLACCODE`) REFERENCES `pr_gl_ca_account` (`ORGACODE`, `GLACCODE`), CONSTRAINT `SQL040126114217562` FOREIGN KEY (`PRODCODE`) REFERENCES `bn_pd_mp_masterprofile` (`PRODCODE`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
以下是两个视图选择
SELECT `a`.`PRODCODE` AS `PRODCODE`, `a`.`SCHEMCODE` AS `SCHEMCODE`, `a`.`BKMSNUMBER` AS `BKMSNUMBER`, `a`.`GNTRDATE` AS `GNTRDATE`, `a`.`GNTRVALUEDAT` AS `GNTRVALUEDAT`, `a`.`GNTREFFECTDAT` AS `GNTREFFECTDAT`, `a`.`GNTRNUMBER` AS `GNTRNUMBER`, `a`.`TRANCODE` AS `TRANCODE`, `a`.`TMODCODE` AS `TMODCODE`, (CASE WHEN ((`a`.`TRANCODE` = '29') AND (`a`.`GNTRDRCR` = 'DR') AND (`a`.`GLACCODE` = `sc`.`GLACCODE`)) THEN COALESCE(`a`.`GNTRAMTFC`,0) END) AS `DISB_AMOUNT`, (CASE WHEN ((`a`.`TRANCODE` = '29') AND (`a`.`GNTRDRCR` = 'CR') AND (`a`.`GLACCODE` = `sc`.`GLACCODE`)) THEN COALESCE(`a`.`GNTRAMTFC`,0) END) AS `DISB_AMOUNT_REV`, (CASE WHEN ((`a`.`TRANCODE` IN ('30','32')) AND (`a`.`GNTRDRCR` = 'CR') AND (COALESCE(`a`.`GNTRSTATUS`,'P') 'C') AND (`a`.`GLACCODE` = `sc`.`GLACCODE`)) THEN COALESCE(`a`.`GNTRAMTFC`,0) END) AS `PRINCIPAL_AMOUNT`, (CASE WHEN ((`a`.`TRANCODE` IN ('30','32')) AND (`a`.`GNTRDRCR` = 'CR') AND (COALESCE(`a`.`GNTRSTATUS`,'P') = 'C') AND (`a`.`GLACCODE` = `sc`.`GLACCODE`)) THEN COALESCE(`a`.`GNTRAMTFC`,0) END) AS `PRINCIPAL_AMOUNT_CANCEL`, (CASE WHEN ((`a`.`TRANCODE` IN ('30','32')) AND (`a`.`GNTRDRCR` = 'DR') AND (`a`.`GLACCODE` = `sc`.`GLACCODE`)) THEN COALESCE(`a`.`GNTRAMTFC`,0) END) AS `PRINCIPAL_AMOUNT_REV`, (CASE WHEN ((`a`.`TRANCODE` IN ('30','73','32')) AND (`a`.`GNTRDRCR` = 'CR') AND (`a`.`GLACCODE` = `sc`.`SCHEPURPOSE`)) THEN COALESCE(`a`.`GNTRAMTFC`,0) END) AS `MARKUP_AMOUNT`, (CASE WHEN ((`a`.`TRANCODE` IN ('30','73','32')) AND (`a`.`GNTRDRCR` = 'DR') AND (`a`.`GLACCODE` = `sc`.`SCHEPURPOSE`)) THEN COALESCE(`a`.`GNTRAMTFC`,0) END) AS `MARKUP_AMOUNT_REV`, (CASE WHEN ((`a`.`TRANCODE` IN ('30','55','32')) AND (`a`.`GNTRDRCR` = 'CR') AND (`a`.`GLACCODE` = `sc`.`CODE_PENALTY`)) THEN COALESCE(`a`.`GNTRAMTFC`,0) END) AS `OTHER_AMOUNT`, (CASE WHEN ((`a`.`TRANCODE` IN ('30','55','32')) AND (`a`.`GNTRDRCR` = 'DR') AND (`a`.`GLACCODE` = `sc`.`CODE_PENALTY`)) THEN COALESCE(`a`.`GNTRAMTFC`,0) END) AS `OTHER_AMOUNT_REV` FROM ((`bn_ms_gt_generaltransaction` `a` JOIN `bn_pd_mp_masterprofile` `mp` ON (((`mp`.`PRODCODE` = `a`.`PRODCODE`) AND (`mp`.`PPC_PRCGCODE` = 'LOAN')))) JOIN `bn_pd_sc_scheme` `sc` ON (((`a`.`PRODCODE` = `sc`.`PRODCODE`) AND (`a`.`SCHEMCODE` = `sc`.`SCHEMCODE`)))) WHERE ((`a`.`TRANCODE` IN('29','30','55','73','32')) AND ((`a`.`GLACCODE` = `sc`.`GLACCODE`) OR (`a`.`GLACCODE` = `sc`.`SCHEPURPOSE`) OR (`a`.`GLACCODE` = `sc`.`CODE_PENALTY`)) AND ((COALESCE(`a`.`GNTRSTATUS`,'P') 'C') OR ((COALESCE(`a`.`GNTRSTATUS`,'P') = 'C') AND (`a`.`GNTRVALUEDAT` = `a`.`GNTRDATE`) AND (`a`.`GNTRVALUEDAT` `a`.`GNTREFFECTDAT`))))
SELECT `a`.`DMP_PRODCODE` AS `DMP_PRODCODE`, `a`.`DCS_SCHEMCODE` AS `DCS_SCHEMCODE`, `a`.`MBM_BKMSNUMBER` AS `MBM_BKMSNUMBER`, `a`.`SGT_GNTRDATE` AS `SGT_GNTRDATE`, `a`.`SGT_GNTRVALUEDAT` AS `SGT_GNTRVALUEDAT`, `a`.`SGT_GNTREFFECTDAT` AS `SGT_GNTREFFECTDAT`, `a`.`SGT_GNTRNUMBER` AS `SGT_GNTRNUMBER`, `a`.`PTR_TRANCODE` AS `PTR_TRANCODE`, `a`.`PTM_TMODCODE` AS `PTM_TMODCODE`, SUM(COALESCE(`a`.`DISB_AMOUNT`,0)) AS `DISB_AMOUNT`, SUM(COALESCE(`a`.`DISB_AMOUNT_REV`,0)) AS `DISB_AMOUNT_REV`, (SUM(COALESCE(`a`.`DISB_AMOUNT`,0)) - SUM(COALESCE(`a`.`DISB_AMOUNT_REV`,0))) AS `TOTAL_DISB`, SUM(COALESCE(`a`.`PRINCIPAL_AMOUNT`,0)) AS `PRINCIPAL_AMOUNT`, SUM(COALESCE(`a`.`PRINCIPAL_AMOUNT_REV`,0)) AS `PRINCIPAL_AMOUNT_REV`, SUM(COALESCE(`a`.`PRINCIPAL_AMOUNT_CANCEL`,0)) AS `PRINCIPAL_AMOUNT_CANCEL`, (SUM(COALESCE(`a`.`PRINCIPAL_AMOUNT`,0)) - SUM(COALESCE(`a`.`PRINCIPAL_AMOUNT_REV`,0))) AS `TOTAL_PRINCIPAL`, SUM(COALESCE(`a`.`MARKUP_AMOUNT`,0)) AS `MARKUP_AMOUNT`, SUM(COALESCE(`a`.`MARKUP_AMOUNT_REV`,0)) AS `MARKUP_AMOUNT_REV`, (SUM(COALESCE(`a`.`MARKUP_AMOUNT`,0)) - SUM(COALESCE(`a`.`MARKUP_AMOUNT_REV`,0))) AS `TOTAL_MARKUP`, SUM(COALESCE(`a`.`OTHER_AMOUNT`,0)) AS `OTHER_AMOUNT`, SUM(COALESCE(`a`.`OTHER_AMOUNT_REV`,0)) AS `OTHER_AMOUNT_REV`, (SUM(COALESCE(`a`.`OTHER_AMOUNT`,0)) - SUM(COALESCE(`a`.`OTHER_AMOUNT_REV`,0))) AS `TOTAL_OTHER` FROM `test_view` `a` GROUP BY `a`.`DMP_PRODCODE`,`a`.`DCS_SCHEMCODE`,`a`.`MBM_BKMSNUMBER`,`a`.`SGT_GNTRDATE`,`a`.`SGT_GNTRVALUEDAT`,`a`.`SGT_GNTREFFECTDAT`,`a`.`SGT_GNTRNUMBER`,`a`.`PTR_TRANCODE`,`a`.`PTM_TMODCODE`$$
第二个视图使用第一个视图。
解释输出:
id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ALL 3564 2 DERIVED mp ref PRIMARY,SQL040126114206120 SQL040126114206120 63 const 3 Using where; Using index; Using temporary; Using filesort 2 DERIVED sc ref PRIMARY PRIMARY 62 mp.PRODCODE 2 2 DERIVED a ref SQL0407170412326,PCA_GLACCODE,GT_ACC_NUM,REPORT_INDEX_2,INDEX_LRDL_GROUPBY,INDEX_LRDL_GROUPBY_LOOSE INDEX_LRDL_GROUPBY 126 mp.PRODCODE,sc.SCHEMCODE 594 Using index condition; Using where
现在,顶部派生表显示使用临时;使用filesort 。
即使创建索引也无济于事。我尝试为松散索引创建分组依据,但不起作用。我错过了什么?
我已经探讨了它并发现了许多变通方法,但没有一个适合我的例子。有些人建议在加入之前在子查询中进行聚合,这是不可能的,因为MySQL不允许FROM子句中的子查询。
创建另一个视图不起作用,因为我需要在求和之前过滤记录
所以,有人可以帮我解决问题。