‘壹’ sql语句执行效率低、速度很慢
算不上优化,按照自己的理解说
1能不用*就不要用*,把你要查询的字段写出来
2 e.RegionName不能在rownum中给检索出来么?感觉在上面检索会块一点点
3 为什么不直接查询你最后要的结果还要中间再查询个totable
4 totable的字查询里month是个无用字段
最后请大神点评以下
‘贰’ 怎么提升这条SQL语句的速度
1.选择最有效率的表名顺序。ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表。
2.WHERE子句中的连接顺序。ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。
3.SELECT子句中尽量避免使用 ‘* ’。
4.使用DECODE函数来减少处理时间。
5.查询结果能不排序就不排序。尽量不用Order by,distinct,union,MINUS,INTERSECT。
6.用表连接代替子查询in。
7.用索引提高查询效率。但是索引不能随便用,还要搞清楚每种索引适用的情况,比如B*索引、复合索引、函数索引、bitmap索引等。虽然使用索引能得到查询效率的提高,但是也必须注意到它的代价. 索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改. 这意味着每条记录的INSERT , DELETE , UPDATE将为此多付出几 次的磁盘I/O,因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。
8.不能再索引列上适用not、<>、is null、not is null、做四则运算,否则索引会被抑制,不起作用,变成全表扫描。
9.用>=替代>。比如SELECT * FROM S WHERE ID>=4效率SELECT * FROM S WHERE ID>3高。两者的区别在于, 前者DBMS将直接跳到第一个ID等于4的记录,而后者将首先定位到ID=3的记录并且向前扫描到第一个DEPT大于3的记录。
10.如果表的数据量很大,可以为该表建分区。经常使用的子查询可以建成视图。
‘叁’ mysql数据库: 为什么sql语句在查询分析中的执行速度远远快于在应用程序的(而且有时候后者慢的很多)
查询分析的执行速度快于应用程序,主要原因在于应用程序查询的时候,需要调用对应的数据库接口驱动程序,如odbc,jdbc等,使得应用程序能够与数据库本身能够交互,这一块一般无法进行优化,可以优化的地方一般是在建立数据库的时候,数据库的逻辑结构和物理结构的优劣直接影响一个系统的性能如何。
‘肆’ 如何解决SQL查询速度太慢
1. 执行计划中明明有使用到索引,为什么执行还是这么慢?
2. 执行计划中显示扫描行数为 644,为什么 slow log 中显示 100 多万行?
a. 我们先看执行计划,选择的索引 “INDX_BIOM_ELOCK_TASK3(TASK_ID)”。结合 sql 来看,因为有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能会更差,优化器选择这个索引避免了排序。
那为什么不选 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很简单,TASK_DATE 字段区分度太低了,走这个索引需要扫描的行数很大,而且还要进行额外的排序,优化器综合判断代价更大,所以就不选这个索引了。不过如果我们强制选择这个索引(用 force index 语法),会看到 SQL 执行速度更快少于 10s,那是因为优化器基于代价的原则并不等价于执行速度的快慢;
b. 再看执行计划中的 type:index,"index" 代表 “全索引扫描”,其实和全表扫描差不多,只是扫描的时候是按照索引次序进行而不是行,主要优点就是避免了排序,但是开销仍然非常大。
Extra:Using where 也意味着扫描完索引后还需要回表进行筛选。一般来说,得保证 type 至少达到 range 级别,最好能达到 ref。
在第 2 点中提到的“慢日志记录Rows_examined: 1161559,看起来是全表扫描”,这里更正为“全索引扫描”,扫描行数确实等于表的行数;
c. 关于执行计划中:“rows:644”,其实这个只是估算值,并不准确,我们分析慢 SQL 时判断准确的扫描行数应该以 slow log 中的 Rows_examined 为准。
4. 优化建议:添加组合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)
优化过程:
TASK_DATE 字段存在索引,但是选择度很低,优化器不会走这个索引,建议后续可以删除这个索引:
select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;+------------+---------------------------+| count(*) | count(distinct TASK_DATE) |+------------+---------------------------+| 1161559 | 223 |+------------+---------------------------+
在这个 sql 中 REL_DEVID 字段从命名上看选择度较高,通过下面 sql 来检验确实如此:
select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;+----------+---------------------------+| count(*) | count(distinct REL_DEVID) |+----------+---------------------------+| 1161559 | 62235 |+----------+---------------------------+
由于有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 组合选择度 100%:
select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;+----------+-----------------------------------+| count(*) | count(distinct REL_DEVID,task_id) |+----------+-----------------------------------+| 1161559 | 1161559 |+----------+-----------------------------------+
在测试环境添加 REL_DEVID,TASK_ID 组合索引,测试 sql 性能:alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);
添加索引后执行计划:
这里还要注意一点“隐式转换”:REL_DEVID 字段数据类型为 varchar,需要在 sql 中加引号:AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'
执行时间从 10s+ 降到 毫秒级别:
1 row in set (0.00 sec)
结论
一个典型的 order by 查询的优化,添加更合适的索引可以避免性能问题:执行计划使用索引并不意味着就能执行快。
‘伍’ sql语句查询速度慢
可以分时操作呀,你把一部分数据融合之后做成视图或者把你的SQL语句写成存储过程。在条件里面尽量少使用“<>”不等于,或者not in,其实这也是告诉你不仅仅从数据结构的方面考虑问题哦
‘陆’ sql语句查询速度是1分钟慢吗
这样的时间程序是有问题了,你这条sql执行需要一分钟,前台就得等一分钟,没有用户会愿意等,现在查询时间都是毫秒级别的,如果查询时间实在减不下来,可以做缓存,或者索引
‘柒’ 如何提高SQL查询速度
1
你老师说的对,建立索引是可以提高查询速度的。你插入了百万条数据,可以测试。如果在C字段上建立索引,那以该字段为查询条件,在建立后查询和删除索引后查询比较一下就知道了。
2
关于视图。是提高不了查询速度的,因为视图对应一个SQL语句,它只是存起来而已,最后需要进行视图消解才能进行查询,它和直接执行相应的语句是一样的,理论上还要慢一点。
3
关于存储过程,弄好了是可以提高查询效率的,因为存储过程会把一段查询,也就是SQL语句进行贤编译,然后将编译后的代码存在于服务器上,在用户查询时节省了SQL的编译时间,所以加快了查询速度。
‘捌’ sql语句和存储过程执行速度的问题
一千万条数据,数据是一样的,执行相同的insert语句
也就是 SQL 语句,只分析一次, 然后执行 一千万次。
理论上 存储过程的会快一点, 因为 存储过程 在 sql 调用的时候,只调用 1次, 然后服务器端 执行 一千万次 insert 操作。 然后返回一次结果给客户端。
sql 语句的话, 要在 sql 客户端 发起 一千万次调用, 服务端执行 一千万次 INSERT操作, 然后 返回 一千万次 执行结果给 客户端。
‘玖’ SQL 语句执行感觉很慢,怎么回事
到这个数量级的全部更新,肯定会很慢。
第一。你的记录不一定在同一个partition,
第二。不明白为什么那么多人建议你建索引,你建的索引越多,你的更新速度越慢,因为你更新记录的同时,还有更新索引。
第三。你必须知道更新速度慢的瓶颈在哪里。是读写太多,还是内存不够,还是CUP不够快,然后对症下药。
下面介绍两个简单的办法,也许有效:
第一:
把这个100W行的表纵向劈成两个,用外键关系连接,一个装小的,经常改变的数据比如ID,外键,状态值,时间等,另一个装大的,不经常改变的数据,比如很长的字符串,xml,text 等。
这样更新时操作小的这个表,可以大大节约内存和CPU 开销,降低磁盘操作。
坏处就是查询时会慢些。
第二:
把这100W行横向切成很多个表,比如每个月的记录装在一个表里,这样每个表的记录数可能只有几万,查询,更新都会快很多。
坏处是查询,更新都不如原来好写。
‘拾’ 如何提高SQL查询速度
索引对数据库检索优化时很重要的一个概念聚集索引在SQL中是唯一的也就是说聚集索引时一个很宝贵的资源但是SQL SERVER在自动分配索引的时候默认总是将ID主键分配为聚集索引其实是很浪费的通常情况下你可以通过语句创建聚集索引到你使用率最高的条件字段上面去,当然你必须先分配聚集索引然后再去分配主键,否则主键创建时就会自动占用聚集索引然后非聚集索引不能设置过滥,设置过滥会导致目录增多最后反而导致查询缓慢优化不是纯粹理论上的东西,理论教会你怎么去使用尝试才能获取经验