【发布时间】:2021-02-18 16:13:55
【问题描述】:
我只是想知道如何在 MySQL 中执行更复杂的查询,而我创建的其中一个查询花费的时间比我预期的要长得多(约 30 秒),我不确定我该怎么做优化查询以更有效地运行。我的查询是为了获取所有之前与我们合作过但在过去 4 个月内未注册为我们目前列出的商店做广告的客户。
我的存档架构如下所示:
|CustomerID | StoreID | DateAdvertised |
|1 | Store1 | 11/01/2020 |
|2 | Store2 | 06/01/2020 |
|1 | Store3 | 08/01/2020 |
. . . .
. . . .
我的客户架构如下所示:
|CustomerID | Name | Email | LastRan | DNC | IsStore |
|1 | Bob | bob@email.com| 2020-11-01 | 1 | 0 |
|2 | Joe | joe@email.com| 2020-06-01 | 0 | 0 |
. . . .
. . . .
我的商店架构如下所示:
|StoreID | Address | Working |
|Store1 | some address | 1 |
|Store2 | some address | 0 |
|Store3 | some address | 1 |
. . . .
. . . .
在我的查询中,我必须获取客户电子邮件、客户姓名和商店地址以及列出的其他存档数据。我创建了一个查询,其中包括 3 个表上的 3 个连接,以便我可以从每个表中获取我需要的数据,我开始认为这是导致我的查询运行缓慢的原因。
这是我正在使用的查询:
SELECT
s.StoreID,
s.Address,
c.Name,
c.CustomerID,
c.LastRan,
c.Email
FROM
Archives a
JOIN
Customers c
JOIN
Stores s ON (a.CustomerID = c.CustomerID
AND a.StoreID = s.StoreID
AND s.Working = '1')
WHERE
c.DNC = '0' AND c.IsStore = '0'
AND c.LastRan != ''
AND c.LastRan != 'N/A'
AND STR_TO_DATE(c.LastRan, '%m/%d/%Y') < '2020-08-01'
GROUP BY c.CustomerID
HAVING Email != '';
我尝试删除该查询最初必须不包含重复的 CustomerID 值的子查询,但我认为使用 group by 会使其更快一点,但并没有太大的区别。我还尝试删除一些我认为不必要的其他检查,但这些也没有什么不同。如果有人对如何优化查询以提高效率有任何建议,那就太好了。蒂亚!
编辑
解释
编辑 2
仅通过在我的存档和客户架构中向 CustomerID 和 StoreID 添加索引似乎可以更快地运行查询。
【问题讨论】:
-
您需要添加查询的 EXPLAIN ANALYZE 和所有表的 create table 以查看此类问题的现有索引
-
@nbk 好的,我会看看我能拉出什么
-
您的 DateAdvertised 列应该是日期类型而不是字符串。不要使用字符串来存储日期
-
@nacho 这会导致性能下降吗?
-
@Luuk 我拥有的档案表是唯一一个在日期格式方面类似的表。不幸的是,我不是那个设置它的人。
标签: mysql