Luk*_*kas 11 mysql performance order-by subquery union query-performance
我刚刚建立了一个日志系统,它由多个具有相同布局的表组成。
每个数据源有一个表。
对于日志查看器,我想
所有表都包含一个称为zeitpunkt索引日期/时间列的字段。
我的第一次尝试是:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730)
ORDER BY zeit DESC LIMIT 10;
Run Code Online (Sandbox Code Playgroud)
优化器无法使用此处的索引,因为来自两个表的所有行都由子查询返回并在UNION.
我的解决方法如下:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
ORDER BY zeit DESC LIMIT 10;
Run Code Online (Sandbox Code Playgroud)
我期望查询引擎会在这里使用索引,因为两个子查询都应该在 之前进行排序和限制UNION,然后合并和排序行。
我真的以为就是这样,但是EXPLAIN在查询上运行告诉我子查询仍然搜索两个表。
EXPLAINing子查询本身向我展示了所需的优化,但UNIONing它们在一起却没有。
我错过了什么?
我知道子查询中的ORDER BY子句在UNION没有 a 的情况下会被忽略LIMIT,但有一个限制。
编辑:
实际上,可能还会有没有account_id条件的查询。
这些表已经存在并且填充了数据。根据来源的不同,布局可能会发生变化,因此我想将它们分开。此外,日志客户端出于某种原因使用不同的凭据。
我必须在日志阅读器和实际表之间保留一层。
以下是整个查询和第一个子查询的执行计划以及详细的表布局:
ype*_*eᵀᴹ 10
只是出于好奇,你能试试这个版本吗?它可能会欺骗优化器使用子查询单独使用的相同索引:
SELECT *
FROM
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
AS a
UNION ALL
SELECT *
FROM
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
AS b
ORDER BY zeit DESC LIMIT 10;
Run Code Online (Sandbox Code Playgroud)
我仍然认为你能拥有的最好的索引是复合(account_id, zeitpunkt)。它会快速产生 10 行,不需要任何技巧。
| 归档时间: |
|
| 查看次数: |
26255 次 |
| 最近记录: |