欢迎访问 生活随笔!

ag凯发k8国际

当前位置: ag凯发k8国际 > 运维知识 > 数据库 >内容正文

数据库

提高mysql查询速度-ag凯发k8国际

发布时间:2024/10/14 数据库 34 豆豆
ag凯发k8国际 收集整理的这篇文章主要介绍了 提高mysql查询速度_如何提高数据库查询速度 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

1、用程序中,

保证在实现功能的基础上,尽量减少对数据库的访问次数;

通过搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担;

能够分开的操作尽量分开处理,提高每次的响应速度;

在数据窗口使用sql时,尽量把使用的索引放在选择的首列;

算法的结构尽量简单;

在查询时,不要过多地使用通配符如select * from t1语句,要用到几列就选择几列如:select col1,col2 from t1;

在可能的情况下尽量限制尽量结果集行数如:select top 300 col1,col2,col3 from t1,因为某些情况下用户是不需要那么多的数据的。

不要在应用中使用数据库游标,游标是非常有用的工具,但比使用常规的、面向集的sql语句需要更大的开销;

按照特定顺序提取数据的查找。

2、避免使用不兼容的数据类型。例如float和int、char和varchar、binary和varbinary是不兼容的。

数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如:

select name from employee where salary > 60000

在这条语句中,如salary字段是money型的,则优化器很难对其进行优化,因为60000是个整型数。

我们应当在编程时将整型转化成为钱币型,而不要等到运行时转化。

3、尽量避免在where子句中对字段进行函数或表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:

select * from t1 where f1/2=100

应改为:

select * from t1 where f1=100*2

select * from record where substring(card_no,1,4)=’5378’

应改为:

select * from record where card_no like ‘5378%’

select member_number, first_name, last_name  from members

where datediff(yy,datofbirth,getdate()) > 21

应改为:

select member_number, first_name, last_name  from members

where dateofbirth < dateadd(yy,-21,getdate())

即:任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。

4、避免使用!=或<>、is null或is not null、in ,not in等这样的操作符,

因为这会使系统无法使用索引,而只能直接搜索表中的数据。例如:

select id from employee where id != 'b%'

优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。

5、尽量使用数字型字段,一部分开发人员和数据库管理人员喜欢把包含数值信息的字段设计为字符型,

这会降低查询和连接的性能,并会增加存储开销。

这是因为引擎在处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

6、合理使用exists,not exists子句。如下所示:

1.select sum(t1.c1)from t1 where(

(select count(*)from t2 where t2.c2=t1.c2>0)

2.select sum(t1.c1) from t1where exists(

select * from t2 where t2.c2=t1.c2)

两者产生相同的结果,但是后者的效率显然要高于前者。因为后者不会产生大量锁定的表扫描或是索引扫描。

如果你想校验表里是否存在某条纪录,不要用count(*)那样效率很低,而且浪费服务器资源。可以用exists代替。如:

if (select count(*) from table_name where column_name = 'xxx')

可以写成:

if exists (select * from table_name where column_name = 'xxx')

经常需要写一个t_sql语句比较一个父结果集和子结果集,从而找到是否存在在父结果集中有而在子结果集中没有的记录,如:

1.select a.hdr_key  from hdr_tbl a---- tbl a 表示tbl用别名a代替

where not exists (select * from dtl_tbl b where a.hdr_key = b.hdr_key)

2.select a.hdr_key  from hdr_tbl a

left join dtl_tbl b on a.hdr_key = b.hdr_key  where b.hdr_key is null

3.select hdr_key  from hdr_tbl

where hdr_key not in (select hdr_key from dtl_tbl)

三种写法都可以得到同样正确的结果,但是效率依次降低。

7、尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。

见如下例子:

select * from t1 where name like ‘%l%’

select * from t1 where substing(name,2,1)=’l’

select * from t1 where name like ‘l%’

即使name字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不对全表所有数据逐条操作来完成任务。

而第三个查询能够使用索引来加快操作。

8、充分利用连接条件,在某种情况下,两个表之间可能不只一个的连接条件,

这时在  where 子句中将连接条件完整的写上,有可能大大提高查询速度。例:

select sum(a.amount) from account a,card b where a.card_no = b.card_no

select sum(a.amount) from account a,card b where a.card_no = b.card_no  and a.account_no=b.account_no

第二句将比第一句执行快得多。

9、消除对大型表行数据的顺序存取,尽管在所有的检查列上都有索引,但某些形式的where子句强迫优化器使用顺序存取。如:

select * from orders where (customer_num=104  and order_num>1001) or order_num=1008

解决办法可以使用并集来避免顺序存取:

select * from orders where customer_num=104 and order_num>1001

union

select * from orders where order_num=1008

这样就能利用索引路径处理查询。

10、避免困难的正规表达式。like关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时间。例如:

select * from customer where zipcode like “98_ _ _”

即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如

果把语句改为select * from customer where zipcode >“98000”,在执行查询

时就会利用索引来查询,显然会大大提高速度。

11、使用视图加速查询。把表的一个子集进行排序并创建视图,有时能加速查询。

它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。例如:

select cust.name,rcvbles.balance,……other columns

from cust,rcvbles

where cust.customer_id = rcvlbes.customer_id

and rcvblls.balance>0

and cust.postcode>“98000”

order by cust.name

如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个

视图中,并按客户的名字进行排序:

create view dbo.v_cust_rcvlbes

as

select cust.name,rcvbles.balance,……other columns

from cust,rcvbles

where cust.customer_id = rcvlbes.customer_id

and rcvblls.balance>0

order by cust.name

然后以下面的方式在视图中查询:

select * from  v_cust_rcvlbes

where postcode>“98000”

视图中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘i/o,所以查询工作量可以得到大幅减少。

12、能够用between的就不要用in

select * from t1 where id in (10,11,12,13,14)

改成:

select * from t1 where id between 10 and 14

因为in会使系统无法使用索引,而只能直接搜索表中的数据。

13、distinct的就不用group by

select orderid  from details where unitprice > 10 group by orderid

可改为:

select distinct orderid from details where unitprice > 10

14、部分利用索引

查询一:

select employeeid, firstname, lastname

from names

where dept = 'prod' or city = 'orlando' or division = 'food'

查询二:

select employeeid, firstname, lastname from names where dept = 'prod'

union all

select employeeid, firstname, lastname from names where city = 'orlando'

union all

select employeeid, firstname, lastname from names where division = 'food'

如果dept列建有索引则查询二可以部分利用索引,查询一则不能。

总结

以上是ag凯发k8国际为你收集整理的提高mysql查询速度_如何提高数据库查询速度的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得ag凯发k8国际网站内容还不错,欢迎将ag凯发k8国际推荐给好友。

网站地图