sql优化

来源:互联网 发布:linux系统如何安装软件 编辑:程序博客网 时间:2024/05/21 10:08

一、优化步骤:

1\通过show status命令查询服务器状态信息,了解当前数据库是以插入更新为主还是以查询操作为主;若是前者,则应关注插入字段是否可为空,

数据是否规整,若是后者,则应注意查询语句是否合理,where中的条件查询时候可以优化

2\定位执行效率较低的sql语句

定位方式:1通过慢查询日志定位那些执行效率低的sql语句,2使用show processlist查看当前mysql的线程

3\通过explain 分析低效sql的执行计划,包括select语句执行过程表如何连接和连接的次序

二、mysql索引不会使用的情况:

1.如果mysql估计使用索引比全表扫描更慢,则不使用索引。例如,如果key_part 1均匀分布在 1 和 100 之间,下列查询中使用索引就不是很好:

  SELECT * FROM table_name where key_part1 > 1 and key_part1 < 901.

2.使用or分割的条件,如果or前的条件中的列有索引,后面的列中没有索引,那么涉及到的所有索引都不会用到

假设两个条件 A1 > 1 OR A2 > 2如果A1或者A2其中之一没索引,那查询必然要遍历全表,有索引的字段便“索引失效了。    如果是单个的索引范围查询,则仍有效

3.复合索引中,如果条件中使用的列不是索引列的第一部分(既不是最左前缀)

4.like是以% 、_开头

三、查询优化:

1.建立索引

2.配置缓存

3.日志分析

4.分库分表

5.优化sql语句,常见规则如下

比如:
select * from table1 where name='zhangsan' and tID > 10000 和执行:
select * from table1 where tID > 10000 and name='zhangsan'
一些人不知道以上两条语句的执行效率是否一样,因为如果简单的从语句先后上看,这两个语句的确是不一样,如果tID是一个聚合索引,那么后一句仅仅从表的10000条以后的记录中查找就行了;而前一句则要先从全表中查找看有几个name='zhangsan'的,而后再根据限制条件条件tID>10000来提出查询结果。
事实上,这样的担心是不必要的。SQL SERVER中有一个“查询分析优化器”,它可以计算出where子句中的搜索条件并确定哪个索引能缩小表扫描的搜索空间,也就是说,它能实现自动优化。

具体要注意的:
1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0
2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。
3.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
4.in 和 not in 也要慎用,因为IN会使系统无法使用索引,而只能直接搜索表中的数据。如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3

5.很多时候用 exists是一个好的选择:
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)
SELECT SUM(T1.C1)FROM T1 WHERE(
(SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0)
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')

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 三星pin码忘记了怎么办 who缺陷精子率98怎么办 吃桃胶脸过敏了怎么办 安卓8.0无法充值怎么办 刚下高速限行怎么办 西安限号外地车怎么办 深圳下高速限行怎么办 物业断业主的电怎么办 物业要求拆除外晾衣架怎么办 安置费一次给了房子没建好怎么办 虎牙充值不到账怎么办 平安保险交20年怎么办 u盘里东西乱码了怎么办 手机指环支架松了怎么办 运动完放屁很臭怎么办 腾讯柒个我要会员怎么办 海风吹的变黑了怎么办 冻豆角炖不烂糊怎么办 腿被热水烫了怎么办 肉和冰箱冻住了怎么办 解冻的肉臭了怎么办 临时用电电缆线破皮怎么办 阳台按自来水墙面脱落怎么办 墙被暖气熏黑了怎么办 下水管比地砖低怎么办 马桶下水管短了怎么办 下水管比马桶低怎么办? 寻常疣液氮冷冻后该怎么办 寻常疣冷冻后起水泡胀痛怎么办 冷冻后大水泡痒怎么办 19岁的宫颈糜烂怎么办 发面酸了没有碱怎么办 面发时间长酸了怎么办 丽珠兰打完红肿怎么办 美的冰柜冷藏室结冰怎么办 胃下午和晚上痛怎么办 二胡弓毛粗拉外弦触到里弦怎么办 电视成黑白的了怎么办 城市居民无钱入社保医保怎么办 老婆说离婚又找不到怎么办 爱一个人太累了怎么办