Mysql 分组查询-为什么这么慢

Mysql 分组查询-为什么这么慢,mysql,group-by,Mysql,Group By,我试图在一个大表(超过800万行)上生成一个组查询。但是,我可以减少按日期分组所有数据的需要。我有一个视图可以捕获我需要的日期,这限制了查询,但这并不是更好。 最后,我需要连接到另一个表以拾取字段 我将在下面显示查询、主表上的create和查询解释 主要查询: SELECT pgi_raw_data.wsp_channel, 'IOM' AS wsp, pgi_raw_data.dated, pgi_accounts.`master`,

我试图在一个大表(超过800万行)上生成一个组查询。但是,我可以减少按日期分组所有数据的需要。我有一个视图可以捕获我需要的日期,这限制了查询,但这并不是更好。 最后,我需要连接到另一个表以拾取字段

我将在下面显示查询、主表上的create和查询解释

主要查询:

SELECT  pgi_raw_data.wsp_channel,
        'IOM' AS wsp,
        pgi_raw_data.dated,
        pgi_accounts.`master`,
        pgi_raw_data.event_id,
        pgi_raw_data.breed,
        Sum(pgi_raw_data.handle),
        Sum(pgi_raw_data.payout),
        Sum(pgi_raw_data.rebate),
        Sum(pgi_raw_data.profit)
FROM    pgi_raw_data
        INNER JOIN summary_max
                ON pgi_raw_data.wsp_channel = summary_max.wsp_channel
                        AND pgi_raw_data.dated > summary_max.race_date
        INNER JOIN pgi_accounts
                ON pgi_raw_data.account = pgi_accounts.account
GROUP   BY pgi_raw_data.event_id
ORDER   BY NULL
创建表时:

 CREATE TABLE `pgi_raw_data` (
  `event_id` char(25) NOT NULL DEFAULT '',
  `wsp_channel` varchar(5) NOT NULL,
  `dated` date NOT NULL,
  `time` time DEFAULT NULL,
  `program` varchar(5) NOT NULL,
  `track` varchar(25) NOT NULL,
  `raceno` tinyint(2) NOT NULL,
  `detail` varchar(30) DEFAULT NULL,
  `ticket` varchar(20) NOT NULL DEFAULT '',
  `breed` varchar(12) NOT NULL,
  `pool` varchar(10) NOT NULL,
  `gross` decimal(11,2) NOT NULL,
  `refunds` decimal(11,2) NOT NULL,
  `handle` decimal(11,2) NOT NULL,
  `payout` decimal(11,4) NOT NULL,
  `rebate` decimal(11,4) NOT NULL,
  `profit` decimal(11,4) NOT NULL,
  `account` mediumint(10) NOT NULL,
  PRIMARY KEY (`event_id`,`ticket`),
  KEY `idx_account` (`account`),
  KEY `idx_wspchannel` (`wsp_channel`,`dated`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
这是我对summary_max的看法:

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW 
 `summary_max` AS select `pgi_summary_tbl`.`wsp_channel` AS 
 `wsp_channel`,max(`pgi_summary_tbl`.`race_date`) AS `race_date` 
from `pgi_summary_tbl` group by `pgi_summary_tbl`.`wsp
以及已计算的查询:

1   PRIMARY <derived2>  ALL                 6   Using temporary

1   PRIMARY pgi_raw_data    ref idx_account,idx_wspchannel  idx_wspchannel  
7   summary_max.wsp_channel 470690  Using where

1   PRIMARY pgi_accounts    ref PRIMARY PRIMARY 3   gf3data_momutech.pgi_raw_data.account   29  Using index

2   DERIVED pgi_summary_tbl ALL                 42282   Using temporary; Using filesort
1个主节点全部6个使用临时节点
1个主pgi_原始_数据参考idx_帐户,idx_WSP通道idx_WSP通道
7总结\u max.wsp\u通道470690使用何处
1个主要pgi_账户参考主要3个gf3data_momutech.pgi_raw_data.account 29使用索引
2个衍生pgi_摘要_tbl所有42282个使用临时文件;使用文件排序

任何有关索引的帮助都会有所帮助。

至少您需要这些字段的索引:

pgi_raw_data.wsp_channel,
pgi_raw_data.dated,  
pgi_raw_data.account
pgi_raw_data.event_id,
summary_max.wsp_channel, 
summary_max.race_date, 
pgi_accounts.account
一般(并非总是)规则是,您正在排序、分组、筛选或加入的任何内容都应该有一个索引

另外:
pgi\u summary\u tbl.wsp


另外,为什么要按null排序?

第一件事是确保在
pgi_摘要_表(wsp_频道,比赛日期)
pgi_帐户(帐户)上有索引。
对于此查询,您不需要原始数据中这些列的索引

MySQL倾向于使用索引,即使它们不是最有效的路径。首先,我将查看“完整”查询的性能,不包括连接:

SELECT  pgi_raw_data.wsp_channel,
        'IOM' AS wsp,
        pgi_raw_data.dated,
        -- pgi_accounts.`master`,
        pgi_raw_data.event_id,
        pgi_raw_data.breed,
        Sum(pgi_raw_data.handle),
        Sum(pgi_raw_data.payout),
        Sum(pgi_raw_data.rebate),
        Sum(pgi_raw_data.profit)
FROM    pgi_raw_data
GROUP   BY pgi_raw_data.event_id
如果这有更好的性能,您可能会遇到索引对您不利的情况。具体问题称为“抖动”。当一个表的位太大而无法放入内存时,就会发生这种情况。通常,处理此类表格的最快方法就是通读整个表格。通过索引访问表可能会导致对大多数行执行额外的I/O操作

如果这样做有效,那么在聚合之后进行连接。另外,考虑更多内存,这样整个表就可以放入内存中。
其次,如果必须处理这种类型的数据,那么按日期对表进行分区可能是一个非常有用的选项。这将允许您显著减少读取大表的开销。您必须确保汇总表可以以相同的方式读取。

pgi_summary_table上的索引是什么??我按null读取排序是有效的,就像它不在那里一样。查询尝试自行排序,而我不需要它。将添加这些索引-event_id是主键,因此不确定是否需要