我的背景是应用程序编程,并且有一条指导方针说在优化方面不要试图“超越”编译器,例如 JIT 等。
SQL查询也是这种情况吗?
我的意思是我已经读到 SQL 服务器为预期是最佳的查询(对吗?)执行某种执行计划,但是是否重新排列/修改实际查询?
还是希望程序员确保查询是最优的?例如先选择然后join
等
4 回答
我的经历(包括为数据库服务器供应商工作)如下。
首先,数据库已经过高度优化,并编译为机器代码(通常用 C 或 C++ 编写)。在现代设备上,大多数操作都非常快,以至于不会注意到次优的执行。
但是,有一些地方需要注意。
如果您没有索引,那么数据库必须进行表扫描,这可能会很慢。许多人只将一个字段放入索引中,但您应该在应用时考虑多个字段。解释实用程序可以向您显示它找到的索引,并建议哪些索引会有所帮助。
共同相关的查询可能很慢。此外,当您有一个带有表达式的 where 子句时,数据库必须为每条记录评估它,并且不能使用索引。
打开连接很慢,所以一定要重用连接,而不是每次操作都重新打开它。
然而,今天最大的问题通常是数据库客户端和数据库服务器之间的网络通信。尽量减少网络转向数据库,并让数据库过滤结果,从而减少需要通过网络发送的数据。
有些事情你想让数据库做,有些事情只有人才能做。数据库管理不能留给数据库本身。人们必须参与。
数据库优化既是一门艺术,也是一门科学。数据库通过从已创建的索引中选择最佳索引,在优化查询方面做得很好。但是,数据库不会自动创建最佳索引。确定最佳索引是什么是 DBA/程序员的工作。
索引可能会使查询变得非常快,但它可能需要 1 GB 的内存。这不是您通常要添加的索引。但是,人们可以查看查询,并意识到只需稍微重新格式化查询即可。
了解数据本身的开发人员能够对使用哪些索引等做出正确的决定。检查您的索引以查看其中一些是否正在使用也很好。有时会创建索引但数据库从未使用过,因为不同的索引总是更好,或者永远不会运行需要索引的搜索。
因此,数据库在如何根据已有的索引最有效地运行查询方面做出了重大决策,但我们的工作是分析数据库是否具有正确的索引并采取适当的措施。
总的来说,这个建议是好的。用于创建优化引擎的人年开发时间比您要管理的要多得多。
也就是说,每个数据库都肯定存在缺陷。在某些情况下,您需要以某种方式表达某些逻辑,以使其更有效率。或者,您可能需要添加提示以获得正确的执行路径。
这是因为 SQL 的优化通常比其他语言的优化要困难得多。它需要了解数据和值的分布以得出最佳解决方案。
我的建议是以最能表达您想要完成的内容的方式编写查询,并使用传达查询目的的命名约定和缩进来编写它们。这样,如果您确实必须修改查询,您至少会了解它在做什么。
在某些情况下,您自己的知识会派上用场。这里有些例子。
1 - 你想要这个月的一切。这很简单
where Year(datefield) = 2013
and month(datefield) = 'February'
但这会跑得更快
where datefield >= '2013-02-01'
and datefield < '2013-03-01'
2 - 你想要男孩叫帕特。性别被索引,名字没有。这更快
where sex = 'M'
and name = 'Pat'
比这个
where name = 'Pat'
and sex = 'M'
3 - 在案例结构中,首先列出最常发生的情况。这个
case when something that almost always happens then 'yes' else 'no' end
会跑得比
case when something that almost never happens then 'no' else 'yes' end