我的 SQL 查询这么慢正常吗?

Posted

技术标签:

【中文标题】我的 SQL 查询这么慢正常吗?【英文标题】:Is it normal for my SQL Query to be this slow? 【发布时间】:2013-01-16 18:27:07 【问题描述】:

我遇到了系统过载的问题。 下面的查询是从 3 个表中获取数据,其中 2 个表的记录超过 10.000 条,运行时间为 50 秒。

SELECT DISTINCT
p.prod_name,
p.prod_price,
Sum(dt.vt_qtd) as total_qtd

FROM tdb_products p 
LEFT JOIN tdb_sales_temp dt ON p.prod_mp_id = dt.vt_product
LEFT JOIN tdb_sales s ON dt.vt_cupom = s.sl_coupom

WHERE
s.sl_day = $day_link AND
s.sl_mon = $mon_link AND
s.sl_year = $year_link

GROUP BY
p.prod_name

ORDER BY
p.prod_name ASC

这正常吗?

已解决!

【问题讨论】:

你有什么索引? 我注意到您在 WHERE 子句中使用了单独的日、月和年列。如果将它们组合为带有索引的单个 DATE 列,则可能会产生很大影响(加上所有 DATE 函数的好处) 使用GROUP BY,是否需要DISTINCT @halfter:因为数据库很乐意接受 prod_name 分组并同时选择 prod_name 和 prod_price,所以它可能是 mysql @halfer: ungrouped prod_priceSELECT 列表中我认为几乎可以解释它 【参考方案1】:
SELECT  prod_name, prod_price, SUM(dt.vt_qtd) AS total_qtd
FROM    tdb_sales s
JOIN    tdb_sales_temp dt
ON      dt.vt_cupom = s.sl_coupom
JOIN    tdb_products p
ON      p.prod_mp_id = dt.vt_product
WHERE   (s.sl_day, s.sl_mon, s_sl_year) = ($day_link, $mon_link, $year_link)
GROUP BY
        p.prod_name -- but it's better to group by product's PRIMARY KEY

删除DISTINCT(这是多余的,因为你有GROUP BY并选择分组字段)

LEFT JOIN 重写为INNER JOIN,因为您在LEFT JOIN'ed 表上有过滤条件。

创建索引:

tdb_sales (sl_year, sl_mon, sl_day, sl_coupom)
tdb_sales_temp (vt_cupom, vt_product)
tdp_product (prod_mp_id) -- it's probably a PRIMARY KEY and you already have it

【讨论】:

天啊!!我创建了索引,响应时间降至 1 秒。谢谢!!!! 为什么创建一个简单的索引会减少时间?有限制吗?再次感谢! @evdutcos:因为这就是索引的用途,提高性能。您是否也重写了查询? @evdutcos 是的,创建索引有一个限制:服务器必须维护索引,因此它会使单独的插入/更新/删除查询慢一点……但你可以看,仔细使用索引,选择方面的改进是显着的。【参考方案2】:

简短的回答是否定的,这绝对不是一个合适的时间长度。任何常见的数据库系统都应该能够以亚秒级的时间处理多个 10,000 行表。

不知道完整的架构或 dbms 后端,我的建议是:

索引 - 确保连接中使用的列有正确的索引 数据类型 - 如果要连接的列的数据类型不同,则 dbms 必须为每个行连接执行转换,这可能会导致显着的性能消耗。

【讨论】:

以上是关于我的 SQL 查询这么慢正常吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 MongoDB 聚合查询这么慢

oracle数据库约200W数据查询非常慢,查询需要10几秒,经常查询超时,这个正常吗?有没有啥好的办法解决

mysql查询六千万条数据不到1s正常吗

一条sql执行很慢可能的原因,如何优化

为啥videoview这么慢?

你的sql查询为什么这么慢?