SQL - 加速查询

时间:2016-04-29 08:44:32

标签: mysql sql query-optimization

我目前使用以下查询,由于数据量大约需要8分钟才能返回结果(大约14个月)。有没有办法让我加快速度呢?

有问题的数据库是带有InnoDb引擎的MySQL

select
    CUSTOMER as CUST,
    SUM(IF(PAGE_TYPE = 'C',PAGE_TYPE_COUNT,0)) AS TOTAL_C,
    SUM(IF(PAGE_TYPE = 'D',PAGE_TYPE_COUNT,0)) AS TOTAL_D
from
        PAGE_HITS
where
    EVE_DATE >= '2016-01-01' and EVE_DATE <= '2016-01-05'
    and SITE =  'P'
    and SITE_SERV like 'serv1X%'
group by
    CUST

数据分区为6个月。进入where子句的每一列都被编入索引。有一些指数&amp;将是一个列在这里的大清单。因此,只需用文字进行总结。对于此查询,EVE_DATE + PAGE_TYPE_COUNT是复合索引之一&amp; CUST + SITE_SERV + EVE_DATEEVE_DATE + SITE_SERVEVE_DATE + SITE

也是如此

主键实际上是一个虚拟自动增量编号。它不是老实说的。我无法访问解释计划。我会看到我能为此做些什么。

我很感激任何帮助来改善这一点。

4 个答案:

答案 0 :(得分:3)

我没有数据,所以我无法测试速度,但我认为它会更快。

select
    CUSTOMER as CUST,
    SUM(PAGE_TYPE_COUNT * (PAGE_TYPE = 'C')) AS TOTAL_C,
    SUM(PAGE_TYPE_COUNT * (PAGE_TYPE = 'D')) AS TOTAL_D
from
        PAGE_HITS
where
    EVE_DATE >= '2016-01-01' and EVE_DATE <= '2016-01-05'
    and SITE =  'P'
    and SITE_SERV like 'serv1X%'
group by
    CUST

在MySql 5.6

上我的小提琴工作得很好

答案 1 :(得分:2)

主要的优化因素是索引。一个应尽可能与您的查询匹配,例如:

EVE_DATE, SITE, CUST, SITE_SERV

顺序很重要,至少对于SITE_SERV作为最后一个值;当您在其上使用LIKE时,您将不会使用完整值,这会降低下一列的索引效率。

通过删除IF并返回类型和计数,您可能也会获得一点点;也许你可以在前端应用程序中处理/格式化这个值?

无论如何,您应该首先使用EXPLAIN分析当前查询,看看出了什么问题。如果你不能,你可以尝试在本地数据库上复制结构,索引和一些虚拟数据,那里的数量是无关紧要的。

答案 2 :(得分:2)

好的,由于表范围分区在EVE_DATE,DBMS应该很容易看到要读取的分区。因此,所有关于使用什么索引的都是。

您检查了一列是否相等(SITE = 'P')。这应该在您的索引中排在第一位。然后,您可以按我猜的顺序添加EVE_DATESITE_SERV。因此,您的索引应该能够尽快找到有问题的表记录。

但是,如果将查询中使用的其他字段添加到索引中,则甚至不必读取该表,因为索引本身中的所有数据都是可用的:

create index on page_hits(site, eve_date, site_serv, customer, page_type, page_type_count);

如果我没弄错的话,这应该是您查询的最佳索引。

答案 3 :(得分:2)

添加以下两个索引:

INDEX(site, date)
INDEX(site, site_serv)

优化器将查看统计信息并在它们之间进行选择。粗略地说,如果“P”和“P”的行数较少,那么第一个会更好。该范围内的日期,而不是'P'和'serv1X%'。

是的,Thorsten可能更好的“覆盖”索引,但它有更多的字段,而不是我想放入索引。

PARTITIONing 可能帮助。但肯定有太少的信息要说。分区可能有帮助的原因是你有一个“二维”查找 - 一个日期范围和'serv1X%'。您需要在date或site_serv上进行分区,然后将PRIMARY KEY(site, ..., ...)与(date或site_serv)中的另一个作为第二列进行分区。其余列需要包括分区键和一些列以使其唯一。这太乱了,我不想考虑它。