使用视图对mysql中的选择进行预排序?

时间:2011-02-16 02:49:09

标签: sql mysql views sql-order-by

我有一个包含两个字段的表a,比如value1和value2。

我将在此表上进行的每一个选择都按照值2 DESC排序,但由于表格相当大,我不能再因为性能问题而“香草”。

我的解决方案是创建一个基本上类似的视图v:

CREATE VIEW v AS SELECT * FROM a ORDER BY value2 DESC

我现在的问题是:

  • 这是一种正确的做法吗?这种排序确实会在我的视图中完成一次而不是每次访问它吗?如果没有,我该怎么办呢?
  • 如何在确保排序保持原样的同时从中选择数据,例如“SELECT * FROM v LIMIT 5”?或者在从视图中读取时是否必须重新指定order by子句(不会丢弃预排序并重做它)?

感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

  

对于我的观点而不是每次访问它时,确实会进行一次排序吗?

不,非物化视图(MySQL不支持物化视图)不会缓存数据 - 它们会针对每个引用执行。

  

如何在确保排序保持原样的同时从中选择数据,例如“SELECT * FROM v LIMIT 5”?或者在从视图中读取时是否必须重新指定order by子句(它不会丢弃预排序并重做它)?

这是为什么ORDER BY永远不应该包含在视图中的一个主要示例。

在视图中,ORDER BY被封装。意思是,您无法看到ORDER BY,并且可能会在视图引用上定义另一个ORDER BY。 ORDER BY不能作为内部查询的谓词推送,因此数据库将运行视图所代表的查询(包括ORDER BY)。在这:

CREATE VIEW your_view AS
  SELECT * FROM YOUR_TABLE ORDER BY value2;

  SELECT *
    FROM your_view
ORDER BY value1;

...将应用外部ORDER BY - 您复制了性能问题,而不是解决它。

ORDER BY是一个必要的邪恶,因为没有其他方法可以保证秩序。 Eli使用MySQL only ALTER TABLE ... ORDER BY的解决方案值得尝试:

ALTER TABLE a ORDER BY value2 DESC;

...但是根据文档,它必须在运行INSERT / UPDATE / DELETE语句后重新运行。

结论

注意在视图中使用ORDER BY(如果有的话)。如果性能确实存在问题,请查看索引并考虑表分区。

答案 1 :(得分:0)

如果您希望每次以 DESC 顺序按“值2”排序整个表格,为什么不这样做呢?

ALTER TABLE `table_name` ORDER BY `value2` DESC;

答案 2 :(得分:0)

  

这是一种正确的做法吗?将   对我来说确实要做的一次   查看而不是每次访问   它?

没有

  

如果没有,我该怎么办?   相反?

首先在value2

上创建索引
  

如何从中选择数据   同时确保排序保持为我   想要,像“SELECT * FROM v   限制5“?

是的,除非查询有自己的ORDER BY,否则将使用视图中的ORDER BY