数据库优化方法总结:
-
对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
但索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时,索引本身也会被修改。 这意味着每条记录的INSERT,DELETE,UPDATE将为此多付出4,5次的磁盘I/O。因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。 -
应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描。备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用NULL。
-
应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。
-
应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描。可以使用union all进行查询(使用union会进行排序删除重复的记录,推荐使用union all)。如:
select id from t where name= 'aaa' union all select id from t where name = 'bbb'
- in和 not in 也要慎用,否则会导致全表扫描。很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)
改为
select num from a where exists(select 1 from b where num=a.num)
- like模糊查询会导致全表扫描。
解决方法:
(1)添加全文索引 (注意:这种方法只适用于mysql引擎是myisam的。此外,MySQL自带的全文索引只能对英文进行全文检索,目前无法对中文进行全文检索。)
--创建article表
CREATE TABLE article (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
content TEXT,
FULLTEXT (title, content) --在title和content列上创建全文索引
);
或者是
ALTER TABLE article
ADD FULLTEXT INDEX fulltext_article (title, content)
查询时的操作:
SELECT * FROM article WHERE MATCH(title, content) AGAINST('查询字符串')
(2)可以考虑查询数据后,在程序里进行模糊查询操作。
- 尽量避免在 where子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
--错误示范
select id from t where num/2 = 100
--应改为
select id from t wherenum = 100*2
- 尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
--错误示范
select id from t where datediff(day,createdate,'2005-11-30') = 0 -–'2005-11-30' --生成的id
--应改为
select id from t where createdate >= '2005-11-30' and createdate < '2005-12-1'
-
Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。
-
对于多张大数据量的表JOIN,要先分页再JOIN。
Select * from big_table e
Inner join (select id from big_table limit 4100000, 10) a on a.id = e.id
-
不考虑null的情况下,主键作为count的条件时候count(主键)最快。count(*)会进行全表扫描,而count(主键)扫描主键的index。
-
尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连 接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
-
尽可能使用varchar而不是char,char占的空间是固定的,用varchar可以节约空间。
-
尽量避免使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
-
WHERE子句后面的条件顺序对大数据量表的查询会产生直接的影响,如:
Select * from zl_yhjbqk where dy_dj = '1K以下' and xh_bz=1
Select * from zl_yhjbqk where xh_bz=1 and dy_dj = '1K以下'
以上两个SQL中dy_dj及xh_bz两个字段都没进行索引,所以执行的时候都是全表扫描,第一条SQL的dy_dj ='1KV以下’条件在记录集内比率为99%,而xh_bz=1的比率只为0.5%,在进行第一条SQL的时候99%条记录都进行dy_dj及xh_bz的比较,而在进行第二条SQL的时候0.5%条记录都进行dy_dj及xh_bz的比较,以此可以得出第二条SQL的CPU占用率明显比第一条低。
- 冗余字段,可以减少join,提高性能。缺点是在更新数据时要同时更新冗余字段。 冗余字段不能随意使用,要根据业务需求,尽量少使用,不能冗余过多字段。