如何从给定查询编写优化查询?

Posted

技术标签:

【中文标题】如何从给定查询编写优化查询?【英文标题】:how to write optimize query from given query? 【发布时间】:2013-11-28 14:22:53 【问题描述】:

我有一个表,其结构是 -

CREATE TABLE `cdr` (`id` bigint(20) NOT NULL AUTO_INCREMENT,
                `dataPacketDownLink` bigint(20) DEFAULT NULL,
                `dataPacketUpLink` bigint(20) DEFAULT NULL,
                `dataPlanEndTime` datetime DEFAULT NULL,
                `dataPlanStartTime` datetime DEFAULT NULL,
                `dataVolumeDownLink` bigint(20) DEFAULT NULL,
                `dataVolumeUpLink` bigint(20) DEFAULT NULL,  
                `dataplan` varchar(255) DEFAULT NULL,  
                `dataplanType` varchar(255) DEFAULT NULL,  
                `createdOn` datetime DEFAULT NULL,  
                `deviceName` varchar(500) DEFAULT NULL,  
                `duration` int(11) NOT NULL,  
                `effectiveDuration` int(11) NOT NULL,  
                `hour` int(11) DEFAULT NULL,  
                `eventDate` datetime DEFAULT NULL,  
                `msisdn` bigint(20) DEFAULT NULL,  
                `quarter` int(11) DEFAULT NULL,  
                `validDays` int(11) DEFAULT NULL,  
                `dataLeft` bigint(20) DEFAULT NULL,  
                `completedOn` datetime DEFAULT NULL,   
            PRIMARY KEY (`id`),   
            KEY `msisdn_index` (`msisdn`),   
            KEY `eventdate_index` (`eventDate`)   
        ) ENGINE=MyISAM AUTO_INCREMENT=55925171 DEFAULT CHARSET=latin1

现在,当我尝试编写此查询时,它从 2000 万条记录中花费了 1 分钟以上 -

select c.msisdn,sum(c.dataVolumeDownLink+c.dataVolumeUpLink) as datasum from cdr c where c.eventDate>=<date> group by c.msisdn order by datasum desc;

实际上我有 40+ 百万条记录。

解释计划-

id  select_type  table  type  possible_keys    key  key_len  ref  rows      Extra                                         
1   SIMPLE       c      ALL   eventdate_index                     20000420  Using where; Using temporary; Using filesort  

我不能进行分区,所以告诉我如何优化这个查询。 谢谢。

【问题讨论】:

【参考方案1】:

优化是一门艺术。

首先在您的 eventDate 上放置一个索引。这可能会让您非常接近,除非您试图寻找一个非常广泛的日期范围,您试图一次获取几乎所有的记录。

其他可能性可能包括在 msisdn 和 eventDate 上创建组合索引。索引中的顺序确实很重要,因此在 msisdn 然后 eventDate 上的索引不同于在 eventDate 然后 msisdn 上的索引。

然后继续使用分析器查看哪些有效,哪些无效。

【讨论】:

谢谢你,布赖恩......你说得对,实际上我正在寻找一个非常广泛的日期范围,为什么优化器不选择索引并读取整个表(解释计划),但是使用复合索引是否好?因为每次我考虑改变结构时,都需要花费大量时间来处理 2000 万条记录。因此,如果我可以制作组合索引,请给我更多的见解。以及您使用哪种分析仪。其实我没有,所以让我知道。并再次感谢您抽出宝贵的时间。 :) 我只是用explain plan,和你一样。对于故障排除,您可能希望创建一个较小版本的表,并在将其应用于 20M 表之前查看哪些工作,这将需要一段时间来建立索引。由于您正在查看所有数据,因此您可以使用 msisdn、eventDate、dataVolumeDownLink、dataVolumeUpLink 的复合索引来做一些很酷的事情,这将接近物化视图。您要考虑的另一件事是将此表用作事务表,然后创建一个报告表,该表使用您需要的数据/信息反映该表 好的,现在我能做的就是测试,这样我就可以通过组合索引来解决这个问题。谢谢 Brian 的帮助。 FB喜欢你的答案(Y)。现在我没有标记你的答案是正确的,因为我想看到更多关于这个话题的回复。

以上是关于如何从给定查询编写优化查询?的主要内容,如果未能解决你的问题,请参考以下文章

SQL -- SQL Server 查询优化器(Query Optimizers)

数据库牛人是如何进行SQL优化的?

优化给定的 sql 查询以提高速度

谁能告诉我如何优化查询?

我如何优化这个子查询?

DBA的五款最佳SQL查询优化工具