需要SQL有效查询

问题描述 投票:0回答:3

我在表中有大约600万行,现在用下面的查询查询表。

SELECT * FROM FD_CPC_HISTORICAL_DATA WHERE id IN (SELECT MAX(id) FROM FD_CPC_HISTORICAL_DATA WHERE fb_ads_account_id=1462257067274960 AND created_at BETWEEN '2019-12-13 00:00:00' AND '2019-12-13 23:59:59' GROUP BY source_text) \G

我已经为fb_ads_account_id,created_at和source_text创建了索引。 id是主键。

我的问题是,即使创建了索引,为什么此查询仍需要9秒钟才能得到结果?

还有其他方法可以更有效地创建此查询吗?

这是mysql解释命令的解释

enter image description here

mysql sql indexing query-optimization sql-execution-plan
3个回答
0
投票

此查询可能无需对同一表进行子查询即可执行,即:

SELECT * FROM FD_CPC_HISTORICAL_DATA WHERE fb_ads_account_id=1462257067274960 AND created_at BETWEEN '2019-12-13 00:00:00' AND '2019-12-13 23:59:59' ORDER BY id DESC LIMIT 1

如果您需要最大ID。或类似的情况,我不确定您是否需要GROUP BY才能获得所需的结果。


0
投票

我认为索引正是您所需要的。 EXPLAIN中令我感到困惑的部分是子查询的(猜测的?)行数与主查询中的行数如此不同。

说实话,我对MYSQL不太熟悉,但是在MSSQL中,我会尝试先将子查询的结果转储到临时表中,在其上放置一个唯一的聚集索引,然后从中选择所有内容。原始表连接到ID列上的所述临时表。 (不要使用IN,请使用JOIN,因为临时表中不能有任何双打)

这可能还会显示所有时间都花在哪里。我的猜测是,这主要是统计问题,但我真的不知道如何在MYSQL中强制更新索引的统计信息。(FLUSH TABLE中有一些关于https://dzone.com/articles/updating-innodb-table-statistics-manually的讨论,但似乎也有一些缺点,请谨慎使用)


0
投票

这是您的查询:

SELECT hd.*
FROM FD_CPC_HISTORICAL_DATA hd
WHERE hd.id IN (SELECT MAX(hd2.id)
                FROM FD_CPC_HISTORICAL_DATA hd2
                WHERE hd2.fb_ads_account_id = 1462257067274960 AND
                      hd2.created_at >= '2019-12-13' AND 
                      hd2.created_at < '2019-12-14'
                GROUP BY source_text
               );

我建议写成:

SELECT hd.*
FROM FD_CPC_HISTORICAL_DATA hd
WHERE hd.fb_ads_account_id = 1462257067274960 AND
      hd.id = (SELECT MAX(hd2.id)
               FROM FD_CPC_HISTORICAL_DATA hd2
               WHERE hd2.fb_ads_account_id = hd.hd.fb_ads_account_id AND
                     hd2.source_text = hd.source_tx AND
                     hd2.created_at >= '2019-12-13' AND 
                     hd2.created_at < '2019-12-14'
               );

对于此查询,您想要FD_CPC_HISTORICAL_DATA(fb_ads_account_id, source_text,created_at)上的索引。

© www.soinside.com 2019 - 2024. All rights reserved.