在 MYSQL 视图中排序多个相似表

Posted

技术标签:

【中文标题】在 MYSQL 视图中排序多个相似表【英文标题】:SORTING OUT MULTIPLE SIMILAR TABLE IN A MYSQL VIEW 【发布时间】:2013-07-18 10:44:43 【问题描述】:

我都, 我有 2 个类似的非常大的表(每个 1M 行),布局相同,我会将它们合并并按一个公共列排序:开始。我也会在“开始”中设置一个条件,即:开始> X。 问题是视图不关心 start 的索引,复杂度上升很多,一个简单的查询大约需要 15 秒,插入 LIMIT 并不能解决,因为结果首先被切断。

CREATE VIEW CDR AS
(SELECT start,    duration, clid, FROM cdr_md ORDER BY start LIMIT 1000) 
 UNION ALL 
 (SELECT start,       duration, clid, FROM cdr_1025 ORDER BY start LIMIT 1000) 
 ORDER BY start ;

查询:

SELECT * FROM CDR WHERE start>10

不返回预期结果,因为 LIMIT 关键字预先切断了结果。

预期结果将是这样的查询:

CREATE VIEW CDR AS
(SELECT start,    duration, clid, FROM cdr_md WHERE start>X ORDER BY start LIMIT 1000) 
UNION ALL 
(SELECT start,    duration, clid, FROM cdr_1025 WHERE start>X ORDER BY start LIMIT 1000) 
 ORDER BY start ;

有没有办法避免这个问题? 谢谢大家 法布里奇奥

【问题讨论】:

您是否在start 上创建了索引? 【参考方案1】:

我有 2 个相似的表...布局相同

这与Principle of Orthogonal Design相反。

不要这样做。至少不是没有非常充分的理由——有了合适的索引,每张表 100 万条记录就足够让 mysql 处理而无需任何分区;并且即使一个确实需要对数据进行分区,也有better ways而不是这个手动的kludge(这可能会产生模棱两可、可能不一致的数据,并导致数据操作代码中的冗余和复杂性) .

相反,请考虑将您的表组合成一个具有适当列的表,以区分记录的差异。例如:

CREATE TABLE cdr_combined AS
  SELECT *, 'md'   AS orig FROM cdr_md
UNION ALL
  SELECT *, '1025' AS orig FROM cdr_1025
;

DROP TABLE cdr_md, cdr_1025;

如果您将始终沿之前的“分区”轴查看数据,请将区分列作为索引前缀包含在内,与使用单独的表相比,性能通常会有所提高。

然后您就不需要执行任何UNION 并且您的VIEW 定义有效地变为:

CREATE VIEW CDR AS
SELECT start, duration, clid, FROM cdr_combined ORDER BY start

但是,请注意,对视图的查询可能并不总是像直接使用基础表一样好。如Restrictions on Views 中所述:

视图处理未优化:

无法在视图上创建索引。

索引可用于使用合并算法处理的视图。但是,使用 temptable 算法处理的视图无法利用其基础表上的索引(尽管可以在生成临时表期间使用索引)。

【讨论】:

非常感谢@eggyal,也许我真的需要重组我的项目。由于更清晰和避免冗余,您的解决方案是最可接受的。也感谢您的迅速

以上是关于在 MYSQL 视图中排序多个相似表的主要内容,如果未能解决你的问题,请参考以下文章

mySQL分组排序

多个表之间 CDC 事件的 Debezium 排序

MySQL JOIN 和 ORDER 问题(对多个表进行排序)

Mysql模糊查询,按相似度排序

视图的概述

MySql 字段排序