SQL语句及索引优化

一、Count()和Max()的优化方法

1、查询最后支付时间-优化max()函数

1)语句:select max(payment_date) from payment;

2)查看执行计划:explain select max(payment_date) from payment \G

3)优化方案(建立索引):create index idx_paydate on payment(payment_date);

2、 在一条SQL中同时查出2006年和2007年电影的数量-优化count()函数

错误的方式:

1)select count(release_year = ‘2006‘ or release_year = ‘2007‘) from film;  // 无法分开计算2006年和2007年的电影数量

2)select count(*) from film where release_year = ‘2006‘ and release_year = ‘2007‘;  // release_year不可能同时为2006和2007,逻辑错误

正确的方式:

select count(release_year = ‘2006‘ or null) as ‘2006年电影数量‘,count(release_year = ‘2007‘ or null) as ‘2007年电影数量‘ from film;

count(*)和count(某一列)讨论:

1)它们值可能不同,count(某一列)所结果是不包含空值(null)的行,而count(*)是包含空值(null)的那行。

二、子查询的优化

通常情况下,需要把子查询优化为join查询,但在优化时要注意关联键是否有一对多的关系,要注意重复数据(使用distinct去重)。

三、优化group by查询

优化前:explain select actor.first_name, actor.last_name, count(*) from skila.film_actor inner join sakila.actor using(actor_id) group by film_actor.actor_id;

优化后:explain select actor.first_name, actor.last_name, c.cnt from sakila.actor inner join ( select actor_id, count(*) as cnt from sakila.film_actor group by actor_id ) as c using(actor_id);

四、优化limit查询

limit常用于分页处理,时常会伴随order by从句使用,因此大多时候会使用filesorts这样会造成大量的IO问题。

优化前:select fiilm_id, description from sakila.film order by title limit 50, 5;

优化步骤1:使用有索引的列或主键进行order by操作

select film_id, description from sakila.film order by film_id limit 50, 5;

优化步骤2:记录上次返回的主键,在下次查询时使用主键过滤

select film_id, des机cription from sakila.flim where film_id > 55 and film_id <= 60 order by film_id limit 1, 5;  // 避免了数据量大时扫描过多的记录(要求主键是顺序增长)

五、如何选择合适的列建立索引

1、在where从句,group by从句,order by从句,on从句中出现的列

2、索引字段越小越好(原因:MySQL的每次读取都以页为单位,如果页中存储的数量越大,则一次IO操作获取的数据量就越大,查询的效率就越高)

3、离散度大的列放到联合索引的前面(离散度越大的列的可选择性越高,因为放在联全索引的前面效率就越好)

select * from payment where staff_id = 2 and customer_id = 584;

选择index(staff_id,customer_id)还是index(customer_id,staff_id)?  由于customer_id的离散度更大,所以应该使用Index(customer_id,staff_id)

判断列的离散程度:

select count ( distinct customer_id ), count ( distinct staff_id ) from payment;  // 唯一值越多则离散度越大

ps:若个索引包含了查询中的所有列,则称该索引为覆盖索引。当我们查询的执行频率非常高,并且查询中所包含的列比较少时,可使用覆盖索引对SQL进行优化。

六、索引的维护及优化---重复及冗余索引

增加索引能提高查询(select)效率,但会影响写入操作(insert、update、delete)的效率。

过多的索引会影响写入操作的效率,同样也会影响查询效率。

重复索引是指相同的列以相同的顺序建立的同类型的索引,如下表中primary key 和 id 列上的索引就是重复索引

create table test(

id int not null primay key,

name varchar(10) not null,

title varchar(50) not null,

unique(id)

)engine=innodb;

冗余索引是指多个索引的前缀列相同,或是在联合索引中包含了主键的索引,下面这个列子中key(name,id)就是一个冗余索引

create table test(

id int not null primay key,

name varchar(10) not null,

title varchar(50) not null,

key(name,id)

)engine=nonodb;

七、索引的维护及优化---查找重复及冗余索引(使用工具更为方便)

select a.table_schema as ‘数据名‘, a.table_name as ‘表名‘,

a.index_name as ‘索引1‘, b.index_name as ‘索引2‘,

a.column_name as ‘重复列名‘ from statistics a join statistics b

on a.table_schema=b.table_schema and a.table_name=b.table_name and a.seq_in_index=b.seq_in_index

and a.column_name=b.column_name where a.seq_in_index=1 and a.index_name<>b.index_name

八、索引的维护及优化---删除不用索引

时间: 2024-10-14 16:44:36

SQL语句及索引优化的相关文章

SQl语句查询性能优化

[摘要]本文从DBMS的查询优化器对SQL查询语句进行性能优化的角度出发,结合数据库理论,从查询表达式及其多种查询条件组合对数据库查询性能优化进行分析,总结出多种提高数据库查询性能优化策略,介绍索引的合理建立和使用以及高质量SQL查询语句的书写原则,从而实现高效的查询,提高系统的可用性. [关键词]SQL查询语句,索引,性能优化 1.引言 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,索引的运用与复杂视图的编写等体会不出SQL语句各种写法的性能优劣,但是应用系统实际应用后,随

3,SQL语句及数据库优化

 1,统一SQL语句的写法 对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的. 所以封装成复用方法,用标准模板来控制. select*from dual select*From dual 其实就是大小写不同,查询分析器就认为是两句不同的SQL语句,必须进行两次解析.生成2个执行计划 2,不要把SQL语句写得太复杂 我经常看到,从数据库中捕捉到的一条SQL语句打印出来有2张A4纸这么长.一般来说这么复杂的语句通常都是有问题的.我拿着这2页长的SQL语句去请教原作者,结果他说

SQL语句及数据库优化

1,统一SQL语句的写法 对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的. 所以封装成复用方法,用标准模板来控制. select*from dual select*From dual 其实就是大小写不同,查询分析器就认为是两句不同的SQL语句,必须进行两次解析.生成2个执行计划 2,不要把SQL语句写得太复杂 我经常看到,从数据库中捕捉到的一条SQL语句打印出来有2张A4纸这么长.一般来说这么复杂的语句通常都是有问题的.我拿着这2页长的SQL语句去请教原作者,结果他说时

几百行SQL语句如何进行优化?

1.对于当下的ORM 框架 EF 以及其他的一些的开源的框架例如Drapper ,以及Sqlite-Sugar 等等,对于查询的速度以及性能确实还不错,但是对于几百条的SQL语句 那么可能就不行了.当在写SQL语句需要注意的规则都无法提高速率的时候,个人认为还是需要传统的ADO.NET 参数化的SQL来进行解决问题. 2.花了2天时间写的SQL查询月结算历史的数据 1 select 2 sum(case when indentdate >= '2015-11-28 00:00:00' and 3

Oracle中查看SQL语句的索引命中情况及CPU占用

第一种: 在PL/SQL中,在Explain plan Window中执行要优化的Sql语句.结果,如下图: Object name列中显示了命中的索引名,Cost列显示了CPU的使用率(%). 第二种: 使用Explain plan for 命令. 1.执行 “explain plan for  要执行的Sql语句;” 2.执行 “select * from table(DBMS_XPLAN.display);”查看结果.如下图

SQL语句-创建索引

  语法:CREATE [索引类型] INDEX 索引名称ON 表名(列名)WITH FILLFACTOR = 填充因子值0~100GO USE 库名GOIF EXISTS (SELECT * FROM SYSINDEXES WHERE NAME='IX_TEST_TNAME')--检测是否已经存在IX_TEST_TNAME索引DROP INDEX TEST.IX_TEST_TNAME--如果存在则删除 --创建索引CREATE NONCLUSTERED INDEX IX_TEST_TNAME

mybatis的sql语句导致索引失效,使得查询超时

mybaitis书写sql需要特别注意where条件中的语句,否则将会导致索引失效,使得查询总是超时.如下语句会出现导致索引失效的情况: with test1 as (select count(C_FUNDACCO) val,'a' v from TINF_REQUEST a where a.C_FUNDCODE = #{cFundcode} and a.D_DATADATE = #{dDatadate}), test2 as (select count(C_FUNDACCO) val,'a'

MySQL中一个sql语句包含in优化问题

第一版sql: SELECT module.id, module.module_name, module.module_code `module` where 92 IN (module.did_access) WHERE module.type =2 AND module.status =0 ORDER BY module.create_time ASC LIMIT 0 , 30 这样的sql语句会有缺陷,in的用法虽然看上去没问题,但是是不对的,这样查出的数据不全,所以优化了一下: 第二版s

SQL语句Not IN优化方案

总结网友们在CSDN社区上对于not in的优化策略,整理如下,备查. select * from emp where emp_no not in (select emp_no from emp_bill) 要求用两种 SQL 写法优化上面 SQL . 方法一. select * from emp a where   not exists ( select 1 from emp_bill b where b.emp_no = a.emp_no) 方法二. select a.* from emp