优化报表的SQL查询

发布于 2024-11-26 13:45:14 字数 782 浏览 0 评论 0原文

这是我写的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜清冷一曲。 2024-12-03 13:45:14

在查询中需要注意三点:

1.“LEFT JOIN”可能会给您带来性能问题。

但是,您需要它,因为 D.MobileNo 值可能不会出现在 SELECT DISTINCT mobile FROM sales 中。任何其他解决办法(是的,有选择)很可能会降低性能。但通过观察接下来的项目,你的表现可能会得到提高。

2. 确保关键列中有索引:

  • D.type
  • S.mobile
  • D.MobileNo
  • D.Username
  • D.Source
  • D.CheckDate

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 in SELECT 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:

  • D.type
  • S.mobile
  • D.MobileNo
  • D.Username
  • D.Source
  • D.CheckDate

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 of CheckDate, specially if Dairy has a large amount of records. The problem is that even if you have an index for CheckDate, it will probably not be used because of the function. Try to filter by CheckDate itself.

江心雾 2024-12-03 13:45:14

如果时间紧迫,那么存储更多数据也是有意义的。

这里,这意味着您为 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文