有哪些DO和DONT使用索引来提高数据库性能?
DO应该是应该创建索引的情况,或者是与索引相关的,可以提高性能的技巧。
如果不应该创建索引,或者其他可能影响性能的索引相关操作,则不要使用DONT。
有哪些DO和DONT使用索引来提高数据库性能?
DO应该是应该创建索引的情况,或者是与索引相关的,可以提高性能的技巧。
如果不应该创建索引,或者其他可能影响性能的索引相关操作,则不要使用DONT。
Answers:
这部分取决于数据库的用途,因为通常索引会减慢插入和更新的速度并加快查询的速度。在数据仓库中,通常没有更新和批处理插入,这使得创建索引和进行大量查询的索引变得更加容易,而查询却被大量索引加速了。在用于网络销售等的在线数据库中,有大量的插入和更新,因此拥有多个精心选择的索引只会降低它的速度。
如果您收到许多特定类型的查询,则可以为查询创建一个索引,尽管在线索引处理比数据仓库更多。如果某些列在查询中出现很多,您可能希望在该列上建立索引,这对于数据仓库尤其有用,因为数据仓库以许多不同且通常是不可预测的方式被查询。
每当您添加或删除索引时,请尝试进行性能测试以查看其效果。没有这些,您就会失明。
关于调优查询和数据库的书籍,通常是特定于一个数据库系统并使用该RDBMS工具的。但是,如果您发现自己需要大量优化数据库,那么您正在进行大量的操作,可能应该雇用具有适当专业知识的DBA。
这在很大程度上取决于您如何使用表格。没有一个简单的答案。
我能给您的最佳建议是:使用调音顾问。他们将在您使用该应用程序时分析数据库命令,然后将对其执行负载测试以为您提供有意义的建议。
它们存在于SQL Server和Oracle中。我不知道其他DBMS是否拥有它们,只是我怀疑它们没有提供这样的基本工具。
很少有随机的建议:
最后建议:如果数据库性能对您的项目确实很重要,请聘请专家。是我做的
a
并且b
是不一样的索引(a, b)
。后者是几乎一样好该指数a
用于对符合条件加快查询a
,是大规模更好地与条件的查询上a
和b
,和是不是在查询有用的b
孤独。(大多数数据库不会使用它。Oracle会使用它,但不会像
@Pierre 303已经说过了,但我会再说一遍。 不要在列的组合上使用索引。(a, b)
对于查询而言,组合索引打开仅a
比对a
单独索引而言稍慢,并且如果您的查询将两个列都合并,则合并索引会更好。有些数据库可以在命中表之前a
和b
之后连接索引,但这远不及合并索引。创建组合索引时,应将最有可能被搜索的列放在组合索引中。
如果你的数据库支持的话,DO穿上,在查询,而不是列显示的功能指标。(如果要在列上调用函数,则该列上的索引是无用的。)
如果您使用的是数据库与真正的临时表,你可以创建和销毁的飞行(如PostgreSQL的,MySQL的,但不是甲骨文),则不要创建临时表的索引。
如果您使用的数据库支持的话(如Oracle),DO锁定良好的查询计划。随着时间的推移,查询优化器将更改查询计划。他们通常会改善计划。但是有时它们会使情况变得更糟。您通常不会真正注意到计划的改进-查询不是瓶颈。但是,一个糟糕的计划可能会使繁忙的站点瘫痪。
不要对你想说的话在大数据负载表的索引。与在加载表时维护索引相比,删除索引,加载数据然后重建索引要快得多。
不要在必须访问大型表中很小一部分的查询上使用索引。(大小取决于硬件。5%是一个不错的经验法则。)例如,如果您的数据包含名称和性别,则名称是索引的不错选择,因为任何给定名称都占总行的一小部分。索引性别并没有帮助,因为您仍然必须访问50%的行。您确实想使用全表扫描。原因是索引结束随机访问大文件,导致您需要磁盘搜索。磁盘搜寻很慢。作为一个例子,我最近设法加快了一个小时的查询,如下所示:
SELECT small_table.id, SUM(big_table.some_value)
FROM small_table
JOIN big_table
ON big_table.small_table_id = small_table.id
GROUP BY small_table.id
通过以下方式重写到3分钟以内:
SELECT small_table.id, big_table_summary.summed_value
FROM small_table
JOIN (
SELECT small_table_id, SUM(some_value) as summed_value
FROM big_table
GROUP BY small_table_id
) big_table_summary
ON big_table_summary.small_table_id = small_table.id
这迫使数据库了解到,不应尝试在上使用诱人的索引big_table.small_table_id
。(一个好的数据库,例如Oracle,应该自行解决。此查询在MySQL上运行。)
更新:这是我所做的磁盘搜索点的说明。索引使您可以快速查找数据在表中的位置。通常这是一个胜利,因为您将只查看需要查看的数据。但并非总是如此,特别是如果您最终将要查看大量数据时。磁盘可以很好地传输数据,但是会使查询变慢。随机查找磁盘上的数据需要1/200秒。慢速查询的版本完成了大约600,000次,耗时近一个小时。(它进行的查找更多,但是缓存捕获了其中的一些。)相比之下,快速版本知道它必须读取所有内容并以70 MB /秒的速度传输数据。它在3分钟内通过了11 GB的表。
基本上,索引可加快搜索速度,但会减慢写入速度,并且会占用空间。那就是要做出的权衡。
经常用于连接,搜索/比较或排序的任何字段都是索引的候选项。要知道它确实是有益的,要衡量一下。但是,具有大量记录(> 1000s)和很少插入的紧密连接表的外键将得到回报。
对于文本字段,您可以在字段的一部分上建立索引(例如,前6个字符),这将加快查询速度,但减轻索引的负担。全文搜索(在上搜索like %substring%
)需要使用不同的技术,而我不熟悉这些技术,因此在此我不能给您提供建议。
索引无济于事的重要情况:在部分日期上搜索(/联接/顺序)时,无法使用完整日期或日期时间字段的索引。上的索引date_created
不会帮助您进行类似的查询select * from t where year(date_created) = 2011
。在mysql中,您无法在部分日期上创建索引。(当您使用' between
而不是year()
它时,可以在日期字段上使用索引。)
手册中有关MYSQL的更多信息:http : //dev.mysql.com/doc/refman/5.6/en/optimization-indexes.html
请执行以下操作:尽量使聚集索引的总大小最小。聚簇索引条目将包含在其他非聚簇索引中,因此有可能浪费磁盘空间。
可以将表视为词典,按照外观顺序(或根本没有帮助顺序)对文章进行排序,将表索引视为该词典的书籍索引。
您可以使用索引来快速查找书中的内容。您无需扫描整本书,只需查找索引中的键(索引通常以某种方式排序(按类别,按科学领域,按历史时期等等),这也意味着您不必扫描整个索引),然后跳到正确的页面。
但是,与书籍不同的是,一张桌子不会被一次印刷然后不可改变。它一直在更新,因此每个索引都必须随之更新。当然,这是在时间和空间上付出代价的,只有通过索引的有用性才能证明这一点。
因此,如果该列在频繁的搜索查询中用作键,请为该列使用索引,否则请不要使用索引。一般而言,“ 频繁 ”一词是一个很好的量词。最后,您必须对哪些是经常使用的做出一个很好的估计,然后在有疑问的情况下简单地对有或没有索引的性能进行基准测试。