The amount of one million data <handling> SQL statement optimization

A: Understanding sql execution order

        In sql , the first is to be performed from statements, each step will generate a virtual table, the table is called when a query for a next step, such as the statement: SELECT column1 Top 10, colum2, max (column3) from User WHERE id> 1 group by column1, colum2 having count (column1)> 1 order by colum2.

      sqlserver 2005 all aspects of the brief:

 

(8)SELECT (9)DISTINCT  (11)<Top Num> <select list>

(1)FROM [left_table]

(3)<join_type> JOIN <right_table>

(2)ON <join_condition>

(4)WHERE <where_condition>

(5)GROUP BY <group_by_list>

(6)WITH <CUBE | RollUP>

(7)HAVING <having_condition>

(10)ORDER BY <order_by_list>

 

   a) the steps Introduction:

  1. FROM : on the FROM clause of a plurality of execution tables Cartesian product ( of Cartesian Product) ( cross-coupling), to generate a virtual table VT1
  2. ON : for VT1 application ON filter. Only those who make <join_condition> true line was only inserted VT2 .
  3. OUTER (the JOIN) : as if specified OUTER the JOIN (relative CROSS JOIN or (INNER JOIN), reservation table ( Preserved Table : LEFT OUTER JOIN the left table marked as reserved table, the right outer join the right table marked as reserved table, a full outer join the two tables are marked as reserved table) match is found as an external row rows are added to VT2, generating VT3. If the FROM clause contains two or more tables, a coupling is generated on the result table and the next table repeat step 1 to step 3 until all tables completely processed.
  4. WHERE : for VT3 application WHERE filter. Only when the <where_condition> is true line was only inserted VT4.
  5. GROUP BY : Press GROUP BY column list of clause VT4 row packet, generating VT5.
  6. CUBE | ROLLUP : the super-group (Suppergroups) insert VT5, generate VT6.
  7. HAVING : to VT6 application HAVING filters. Only when the <having_condition> is true group will be inserted VT7.
  8. SELECT : processing SELECT list, resulting in VT8.
  9. The DISTINCT : duplicate rows from VT8 is removed, resulting in VT9.
  10. ORDER BY : the VT9 rows by ORDER BY sorted column list clause, generate a cursor ( VClO).
  11. The TOP : From VC10 choose to specify the number or proportion of start of the line, the table generating VT11, and returns to the caller .

 

  b) Standard sql execution order is:

  1: form assembly of data from different tables, such as the form user or, form user U the Join goodsOrder AS AS = R & lt ON u.id r.userid

  2: where filtering data that meets the search criteria, such as: ID> 1000

  3: group by the query to group data

  4: Use sum like aggregate functions are calculated.

  5: Use having screened group.

  6: execute select language

  7: perform the sort statement

  如:select count(gid),gname from shopping_goods where gcid=1 group by gname having count(gid)>1 order by count(gid) desc

  1: Home query shopping_goods table, get the data in the table

  2: execution where, filtered gcid = 1 product.

  3: for gname group.

  4:使用聚合函数count(),计算出商品类型为1,不同商品名称的数量.

  5:使用having,过滤出类型为1,商品统计数量大于1的商品

  6:执行select语句

  7:执行order by ,按照商品数量降序排列。

二:百万数据量优化

  这里只介绍查询和修改的方法,如果是系统优化,需要从表结构,索引,表分区等方面处理。

  1:合理使用索引,在一个大数据量的表中,并不是索引越多越好,索引越多,写操作越慢,建议在以下字段上创建索引。

  在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。

  在频繁进行排序或分组(即进行group byorder by操作)的列上建立索引。

  在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员表的性别列上只有两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。

  如果待排序的列有多个,可以在这些列上建立复合索引(compound index)。

  使用系统工具。如Informix数据库有一个tbcheck工具,可以在可疑的索引上进行检查。在一些数据库服务器上,索引可能失效或者因为频繁操作而使得读取效率降低,如果一个使用索引的查询不明不白地慢下来,可以试着用tbcheck工具检查索引的完整性,必要时进行修复。另外,当数据库表更新大量数据后,删除并重建索引可以提高查询速度。

  2:尽量少用(或者不用)sqlserver 自带的函数

  a):dateadd(month,-1,getdate()),请使用time>'2017-09-19 23:42:44.770 '代替dateadd.

  b):datediff(day,'2017-10-20','2017-10-25'),select datepart(day,getdate());,如需计算两个日期之前的差值,或者得到日期中的整数部分,建议查询完毕后用java程序来计算,不要什么都让数据库来做.

  c:) 如:substring(name,1,3) = ’abc’,建议修改为 name like 'abc%'

 

  3:尽量不要在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,强烈建议where涉及的列,不要留空,创建表时赋予初始值

错误
select id from table where name is not null
正确
create table table(name varchar(20) default '')

   4:应尽量避免在 where 子句中使用 != <> 操作符,否则将引擎放弃使用索引而进行全表扫描。

   

错误

select id from table where id <> 100 

  5:应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描,建议使用unall 来代替or

  

select id from table where num=1 or Name = 'zhangsan'

建议修改为

select id from table where num=1 

unionall 

select id from table where  name = 'zhangsan'

  6:建议使用exists 来代替in,能用between 就不要使用in 如:age in (20,21,22)建议修改为:age between 20 and 22

  
select id from t where role in (select rid from role where rName = '经理')

建议修改为

select id from t as a where exists (select rid from role  as b where a.role  = b.rid and rName = '经理')

  7:like 的用法

  除了 title  like '重庆%' ,其它使用方法(如:title like  '%%' title like '%')也将导致全表扫描

    8:where 中尽量不要出现表达式计算

  如:

select id from t where num/2 = 100

  应改为:

select id from t where num = 100*2

  9:Update 语句,如果只更改12个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。强烈建议修改时使用动态sql语句,类似hibernatedynamic-update=true,不过hibernate需要将修改对像通过id查询出来,才会动态修改,如果是普通sql,直接组装就可以。

  10:对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差.

  11:不要写一些没有意义的查询,如需要生成一个空表结构:

select col1,col2 into #t from t where 1=0

 

  12:尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连 接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

  13:尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

  14:不建议使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

  15:尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

  16:在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

  17:尽量避免大事务操作,提高系统并发能力。并且不要事务嵌套,不要在事务中去调用其它系统的接口,不要在事务中耗时操作,不然死锁并伴你左右

  18:尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。(笔者曾经处理过,从3000万手机号码库中,模糊查询出上万个手机号码,这种需求是客户硬性要求,就要通过executorservice了,不要直接写sql)

19:如果数据库是mysql,一定要利用数据库引擎,不同业务要使用不同的数据库引擎。比如常用的innodbmyisam,innodb支持事务,支持外键,锁是表级锁,缺点是查询速度慢,Myisam 的执行速度更快,性能更好,但不支持外键,不支持事务,锁是行锁级。比如日志表,数据量大,强烈建议使用myisam引擎.

Guess you like

Origin www.cnblogs.com/bugo/p/10994424.html