百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>数据库> 数据库查询怎样优化机能?(详解)
分享文章到:

数据库查询怎样优化机能?(详解)

发布时间:09/01 来源:未知 浏览: 关键词:
查询是数据库技术中最常用的操纵,本文就在MySQL中常用的查询优化技术进行计议。计议的内容有:通过查询缓冲提高查询速度;MySQL对查询的主动优化;基于索引的排序;不成达查询的检测和运用各种查询选中来提高机能。

SELECT * from TABLE1
SELECT * FROM TABLE1

上面的两条SQL语句关于查询缓冲是完全不一样的SELECT。并且查询缓冲并不主动处置空格,因而,在写SQL语句时,应尽量减少空格的运用,尤为是在SQL首和尾的空格(由于,查询缓冲并不主动截取首尾空格)。

虽然不设定查询缓冲,有时可能带来机能上的亏损,但有一些SQL语句需要实时地查询数据,或者并不时常运用(可能一天就施行一两次)。这样就需要把缓冲关了。固然,这可以通过设定query_cache_type的值来关闭查询缓冲,但这就将查询缓冲永恒地关闭了。在MySQL 5.0中供给了一种可以暂时关闭查询缓冲的办法:

SELECT SQL_NO_CACHE field1, field2 FROM TABLE1

以上的SQL语句因为运用了SQL_NO_CACHE,因而,无论这条SQL语句可否被施行过,办事器都不会在缓冲区中查寻,每次都会施行它。
我们还可以将my.ini中的query_cache_type设成2,这样只要在运用了SQL_CACHE后,才运用查询缓冲。

SELECT SQL_CALHE * FROM TABLE1

二、MySQL对查询的主动优化

索引关于数据库是非常重要的。在查询时可以通过索引来提高机能。但有时运用索引反而会落低机能。我们可以看如下的SALES表:

CREATE TABLE SALES
(
ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
NAME VARCHAR(100) NOT NULL,
PRICE FLOAT NOT NULL,
SALE_COUNT INT NOT NULL,
SALE_DATE DATE NOT NULL,
PRIMARY KEY(ID),
INDEX (NAME),
INDEX (SALE_DATE)
)

假如这个表中保留了数百万条数据,而我们要查询商品号为1000的商品在2004年和2005年的均匀价钱。我们可以写如下的SQL语句:

SELECT AVG(PRICE) FROM SALES
WHERE ID = 1000 AND SALE_DATE BETWEEN '2004-01-01' AND '2005-12-31';

要是这种商品的数目非常多,差未几占了SALES表的记载的50%或更多。那么运用SALE_DATE字段上索引来盘算均匀数就有些慢。由于要是运用索引,就得对索引进行排序操纵。当知足前提的记载非常多时(如占整个表的记载的50%或更多的比例),速度会变慢,这样还不如对整个表进行扫描。因而,MySQL会主动依据知足前提的数据占整个表的数据的比例主动决议可否运用索引进行查询。

关于MySQL来说,上述的查询效果占整个表的记载的比例是30%摆布时就不运用索引了,这个比例是MySQL的开发人员依据他们的经验得出的。然而,现实的比例值会依据所运用的数据库引擎不一样而不一样

三、 基于索引的排序

MySQL的弱点之一是它的排序。虽然MySQL可以在1秒中查询大概15,000笔记录,但因为MySQL在查询时最多只能运用一个索引。因而,要是WHERE前提已经占用了索引,那么在排序中就不运用索引了,这将大大落低查询的速度。我们可以看看如下的SQL语句:

SELECT * FROM SALES WHERE NAME = “name” ORDER BY SALE_DATE DESC;

在以上的SQL的WHERE子句中已经运用了NAME字段上的索引,因而,在对SALE_DATE进行排序时将不再运用索引。为理解决这个题目,我们可以对SALES表创立复合索引:

ALTER TABLE SALES DROP INDEX NAME, ADD INDEX (NAME, SALE_DATE)

这样再运用上述的SELECT语句进行查询时速度就会大副提拔。但要注意,在运用这个办法时,要确保WHERE子句中没有排序字段,在上例中就是不克不及用SALE_DATE进行查询,不然虽然排序快了,但是SALE_DATE字段上没有独自的索引,因而查询又会慢下来。

四、 不成达查询的检测

在施行SQL语句时,未免会碰到一些必假的前提。所谓必假的前提是不管表中的数据怎样变化,这个前提都为假。如WHERE value 200。我们永远没法寻到一个既小于100又大于200的数。
要是碰到这样的查询前提,再去施行这样的SQL语句就是画蛇添足。幸亏MySQL可以主动检测这种状况。如我们可以看看如下的SQL语句:

SELECT * FROM SALES WHERE NAME = “name1” AND NAME = “name2”

以上的查询语句要查寻NAME既等于name1又等于name2的记载。很显明,这是一个不成达的查询,WHERE前提一定是假。MySQL在施行SQL语句以前,会先剖析WHERE前提可否是不成达的查询,要是是,就不再施行这条SQL语句了。为了验证这一点。我们第一对如下的SQL运用EXPLAIN进行测试:

EXPLAIN SELECT * FROM SALES WHERE NAME = “name1”

上面的查询是一个正常的查询,我们可以看到运用EXPLAIN返回的施行信息数据中table项是SALES。这注明MySQL对SALES进行操纵了。再看看下面的语句:

EXPLAIN SELECT * FROM SALES WHERE NAME = “name1” AND NAME = “name2”

我们可以看到,table项是空,这注明MySQL并没有对SALES表进行操纵。

五、 运用各种查询选中来提高机能

SELECT语句除了正常的运用外,MySQL还为我们供给了许多可以加强查询机能的选项。如上面介绍的用于控制查询缓冲的SQL_NO_CACHE和SQL_CACHE就是其中两个选项。在这一局部,我将介绍几个常用的查询选项。

1. STRAIGHT_JOIN:强迫连贯次序

当我们将两个或多个表连贯起来进行查询时,我们并不消体贴MySQL先连哪个表,后连哪个表。而这一切都是由MySQL内部通过一系列的盘算、评估,最后得出的一个连贯次序决议的。如以下的SQL语句中,TABLE1和TABLE2并纷歧定是谁连贯谁:

SELECT TABLE1.FIELD1, TABLE2.FIELD2 FROM TABLE1 ,TABLE2 WHERE …

要是开发人员需要人为地干涉连贯的次序,就得运用STRAIGHT_JOIN关键字,如以下的SQL语句:

SELECT TABLE1.FIELD1, TABLE2.FIELD2 FROM TABLE1 STRAIGHT_JOIN TABLE2 WHERE …

由上面的SQL语句可知,通过STRAIGHT_JOIN强制MySQL按TABLE1、TABLE2的次序连贯表。要是你以为按本人的次序比MySQL举荐的次序进行连贯的效率高的话,就可以通过STRAIGHT_JOIN来肯定连贯次序。

2. 干涉索引运用,提高机能

在上面已经提到了索引的运用。个别状况下,在查询时MySQL将本人决议可否运用索引,运用哪一个索引。但在一些特别状况下,我们但愿MySQL只运用一个或几个索引,或者不但愿运用某个索引。这就需要运用MySQL的控制索引的一些查询选项。

限定运用索引的范畴:

有时我们在数据表里创立了许多索引,当MySQL对索引进行选中时,这些索引都在考虑的范畴内。但有时我们但愿MySQL只考虑几个索引,而不是全部的索引,这就需要用到USE INDEX对查询语句进行设定。

SELECT * FROM TABLE1 USE INDEX (FIELD1, FIELD2) …

从以上SQL语句可以看出,不管在TABLE1中已经创立了多少个索引,MySQL在选中索引时,只考虑在FIELD1和FIELD2上创立的索引。

限定不运用索引的范畴

要是我们要考虑的索引许多,而不被运用的索引又很少时,可以运用IGNORE INDEX进行反向拔取。在上面的例子中是选中被考虑的索引,而运用IGNORE INDEX是选中不被考虑的索引。

SELECT * FROM TABLE1 IGNORE INDEX (FIELD1, FIELD2) …

在上面的SQL语句中,TABLE1表中只要FIELD1和FIELD2上的索引不被运用。

强制运用某一个索引

上面的两个例子都是给MySQL供给一个选中,也就是说MySQL并纷歧定要运用这些索引。而有时我们但愿MySQL必需要运用某一个索引(因为MySQL在查询时只能运用一个索引,因而只能强制MySQL运用一个索引)。这就需要运用FORCE INDEX来完成这个功能。

SELECT * FROM TABLE1 FORCE INDEX (FIELD1) …

以上的SQL语句只运用创立在FIELD1上的索引,而不运用其它字段上的索引。

3. 运用暂时表供给查询机能

当我们查询的效果集中的数据比拼多时,可以通过SQL_BUFFER_RESULT.选项强迫将效果集放来临时表中,这样就可以很快地开释MySQL的表锁(这样其它的SQL语句就可以对这些记载进行查询了),而且可以长工夫地为客户端供给大记载集。

SELECT SQL_BUFFER_RESULT * FROM TABLE1 WHERE …

和SQL_BUFFER_RESULT.选项相似的还有SQL_BIG_RESULT,这个选项个别用于分组或DISTINCT关键字,这个选项通知MySQL,要是有须要,就将查询效果放来临时表中,甚至在暂时表中进行排序。

SELECT SQL_BUFFER_RESULT FIELD1, COUNT(*) FROM TABLE1 GROUP BY FIELD1

六、 结论
在程序设计中一样存在一个“二八准则”,即20%的代码用去了80%的工夫。数据库利用程序的开发亦然。数据库利用程序的优化,重点在于SQL的施行效率。而数据查询优化的重点,则是使得数据库办事器少从磁盘中读数据以及次序读页而不是非次序读页。

举荐教程:《MySQL教程》

以上就是数据库查询怎样优化机能?(详解)的细致内容,更多请关注 百分百源码网 其它相干文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有153人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板