优化报表的SQL查询
这是我写的 SQL 查询,它工作正常,但速度很慢。
SELECT D.Username,
SUM(CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN D.type = 'No' THEN 1 ELSE 0 END) as No,
SUM(CASE WHEN D.type = '' THEN 1 ELSE 0 END) as Other,
SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales,
COUNT(*) as TOTAL FROM dairy as D
LEFT JOIN (SELECT DISTINCT mobile FROM sales) as S on D.MobileNo = S.mobile
WHERE source = 'Network' AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1309561200
group by D.Username order by TOTAL DESC
正如您所看到的,它统计了“是”、“否”、“其他”以及匹配的 MobileNo (D.MobileNo = S.mobile
) 销售数量。
我尝试过向类型、用户名、移动设备、MobileNO、CheckDate 和源添加索引 - 性能并没有提高太多。
This is SQL query I wrote, it work fine but it is slow.
SELECT D.Username,
SUM(CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN D.type = 'No' THEN 1 ELSE 0 END) as No,
SUM(CASE WHEN D.type = '' THEN 1 ELSE 0 END) as Other,
SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales,
COUNT(*) as TOTAL FROM dairy as D
LEFT JOIN (SELECT DISTINCT mobile FROM sales) as S on D.MobileNo = S.mobile
WHERE source = 'Network' AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1309561200
group by D.Username order by TOTAL DESC
As you can see it count number of Yes, No, Other and the matching MobileNo (D.MobileNo = S.mobile
) sale.
I have tried adding index to type, username, mobile, MobileNO, CheckDate and source - the performance did not improve much.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在查询中需要注意三点:
1.“LEFT JOIN”可能会给您带来性能问题。
但是,您需要它,因为
D.MobileNo
值可能不会出现在SELECT DISTINCT mobile FROM sales
中。任何其他解决办法(是的,有选择)很可能会降低性能。但通过观察接下来的项目,你的表现可能会得到提高。2. 确保关键列中有索引:
3. 您可能在按“UNIX_TIMESTAMP(CheckDate)”进行过滤时遇到问题
这可能是关键问题。您在按
UNIX_TIMESTAMP(CheckDate)
而不是CheckDate
进行过滤时可能会遇到问题,特别是在Dairy
拥有大量记录的情况下。问题是,即使您有CheckDate
的索引,由于该函数的原因,它也可能不会被使用。尝试按CheckDate
本身进行过滤。Three points to notice in your query:
1. There's a chance the `LEFT JOIN` is giving you performance issues.
However, you need it, since it is possible that there are
D.MobileNo
values that will not be present inSELECT DISTINCT mobile FROM sales
. Any other work around (yes, there are options) will most likely decrease performance. But your performance might be improved by observing the next items.2. Make sure you have indexes in the key columns:
3. You might be having problems with filtering by `UNIX_TIMESTAMP(CheckDate)`
This might be the key issue. You might be having problems with filtering by
UNIX_TIMESTAMP(CheckDate)
instead ofCheckDate
, specially ifDairy
has a large amount of records. The problem is that even if you have an index forCheckDate
, it will probably not be used because of the function. Try to filter byCheckDate
itself.如果时间紧迫,那么存储更多数据也是有意义的。
这里,这意味着您为 YesValue、NoValue、OtherValue 添加 INT 列,并在应用程序中用 0 或 1 填充它们。通过这样做,您可以从 SELECT 部分中删除案例计算。
另请发布当前可用的所有索引以及注释中所说的表的 CREATE 语句。
If this is time critical it can also make sense to store more data.
Here this means that you add INT columns for YesValue, NoValue, OtherValue and fill them with 0 or 1 in your application. By doing this you can remove the case calculations from your SELECT-part.
Also please post all indexes currently available and as the comments say the CREATE-statement for the table.