例句1:SELECT a.pl_id,a.pl_license,a.pp_id,a.pp_name,a.pl_num,a.pl_lock,ple.ple_name,ple.ple_time,ple.ple_register from (SELECT pl.pl_id,pl.pl_license,pl.pp_id,pp.pp_name,pl.pl_num,pl.pl_lock from pay_license pl INNER JOIN pay_product pp ON pp.pp_id = pl.pp_id WHERE 1 AND pp.pp_type = 'ENT') a left JOIN pay_license_ent ple ON ple.pl_id = a.pl_id order by ple.ple_time desc 例句2:SELECT pl.pl_id,pl.pl_license,pp.pp_id,pp.pp_name,pl.pl_num,pl.pl_lock,ple.ple_name,ple.ple_time,ple.ple_register FROM pay_license pl INNER JOIN pay_product pp ON pp.pp_id = pl.pp_id left JOIN pay_license_ent ple ON ple.pl_id = pl.pl_id WHERE 1 AND pp.pp_type = 'ENT' order by ple.ple_time desc如以上2個例句,表pay_license中有40W條記錄。。表pay_license_ent和表pay_product 中分別都有100條記錄檔不用查詢分析器的時候,用肉眼怎么判斷這兩句SQL的執行速度。
1. 例句1写法不地道,那个子查询没有必要,理论上肯定比例句2效率低。2. order by子句也可能比较耗时,并影响索引的使用,你可以把它去掉再比较下。3. 由于pay_license_ent和pay_product 两个表数据量很小,可以考虑先联这两个表。--try: SELECT pl.pl_id,pl.pl_license,pp.pp_id,pp.pp_name,pl.pl_num,pl.pl_lock ,ple.ple_name,ple.ple_time,ple.ple_register FROM pay_product pp left JOIN pay_license_ent ple ON ple.pl_id = pl.pl_id INNER JOIN pay_license pl ON pp.pp_id = pl.pp_id WHERE pp.pp_type = 'ENT' order by ple.ple_time desc
其實2個句子執行起來都沒錯誤的 例句1: SELECT a.pl_id,a.pl_license,a.pp_id,a.pp_name,a.pl_num,a.pl_lock,ple.ple_name,ple.ple_time,ple.ple_register from (SELECT pl.pl_id,pl.pl_license,pl.pp_id,pp.pp_name,pl.pl_num,pl.pl_lock from pay_license pl INNER JOIN pay_product pp ON pp.pp_id = pl.pp_id WHERE 1 AND pp.pp_type = 'ENT' limit 0,10) a left JOIN pay_license_ent ple ON ple.pl_id = a.pl_id order by ple.ple_time desc 這樣執行起來比例句2效率要高很多我現在想要的結果是 當我不執行例句1和例句2,只是單單的靠肉眼分析的話,時候能判斷出什麽的語句快什麽樣的語句慢
看连接,left join 肯定没 inner join 效率高!
set statistics time on set statistics io on == +执行计划
select * from a inner join b where b.c=1 select * from a inner join b where a.c=1 速度差很多,请自己测试
有两种方法,自己研究一下吧:1. SET STATISTICS PROFILE ON SET STATISTICS IO ON SET STATISTICS TIME ON GO --你的SQL脚本 GO SET STATISTICS PROFILE OFF SET STATISTICS IO OFF SET STATISTICS TIME OFF 2. SET SHOWPLAN_ALL ON; GO --你的SQL脚本 GO SET SHOWPLAN_ALL OFF;
用where代替having
多用别名
多用系统自带内部函数
楼主的那两条语句好像一样啊,
那个只是先将前两个连接,再与后一个连接,
后面那条就是连接!!
LZ给的句子有语法错误:...where 1 AND ...
SELECT pl.pl_id,pl.pl_license,pp.pp_id,pp.pp_name,pl.pl_num,pl.pl_lock
,ple.ple_name,ple.ple_time,ple.ple_register
FROM pay_product pp
left JOIN pay_license_ent ple ON ple.pl_id = pl.pl_id
INNER JOIN pay_license pl ON pp.pp_id = pl.pp_id
WHERE pp.pp_type = 'ENT'
order by ple.ple_time desc
例句1:
SELECT a.pl_id,a.pl_license,a.pp_id,a.pp_name,a.pl_num,a.pl_lock,ple.ple_name,ple.ple_time,ple.ple_register from (SELECT pl.pl_id,pl.pl_license,pl.pp_id,pp.pp_name,pl.pl_num,pl.pl_lock from pay_license pl INNER JOIN pay_product pp ON pp.pp_id = pl.pp_id WHERE 1 AND pp.pp_type = 'ENT' limit 0,10) a left JOIN pay_license_ent ple ON ple.pl_id = a.pl_id order by ple.ple_time desc 這樣執行起來比例句2效率要高很多我現在想要的結果是 當我不執行例句1和例句2,只是單單的靠肉眼分析的話,時候能判斷出什麽的語句快什麽樣的語句慢
set statistics io on
==
+执行计划
問題是現在這邊只能用 left join
多多的了解一些SQL语句优化的知识,在日常的开发中很重要。
下面是一个例子12:40:13 SQL> select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss' ) nowNOW
-------------------
2009-07-03 12:40:46已用时间: 00: 00: 00.00Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1)
1 0 FAST DUAL (Cost=2 Card=1)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
238 bytes sent via SQL*Net to client
277 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed12:40:46 SQL>
2. 一看见带 cursor的游标就知道占用资源, 速度自然不快
3. 一看见一个语句用了三层以上的子查询就知道效率不行
4. 一看见字段参与的计算表达式放在where条件后的等式左边就知道速度差
5. 一看见where条件后的等式有getdate()就知道不严格, 因为如果有N条记录其实此时getdate()函数是调用N次, 当次没有调用一次快哟
6. 一看动态执行语句(在查询分析器里是红瞎瞎的一片)就知道非常的没有效率,因为根本没有索引优化, 也没有预编译的好处, 有时候的确不得不用动态执行, 尽量用在数据量非常小的场合
1 加索引
2 少有排序
3 慎用in
================
1、关键字段建立索引。
2、使用存储过程,它使SQL变得更加灵活和高效。
3、备份数据库和清除垃圾数据。
4、SQL语句语法的优化。(可以用Sybase的SQL Expert,可惜我没找到unexpired的
序列号)
5、清理删除日志。SQL语句优化的原则:
==================
1、使用索引来更快地遍历表。
缺省情况下建立的索引是非群集索引,但有时它并不是最佳的。在非群集索引
下,数据在物理上随机存放在数据页上。合理的索引设计要建立在
对各种查询的分析和预测上。一般来说:①.有大量重复值、且经常有范围查询
(between, > ,< ,> =,< =)和order by、group by发生的列,可考
虑建立群集索引;②.经常同时存取多列,且每列都含有重复值可考虑建立组合索引
;③.组合索引要尽量使关键查询形成索引覆盖,其前导列一定
是使用最频繁的列。索引虽有助于提高性能但不是索引越多越好,恰好相反过多的索
引会导致系统低效。用户在表中每加进一个索引,维护索引集
合就要做相应的更新工作。
2、IS NULL 与 IS NOT NULL
不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有
多列这样的情况下,只要这些列中有一列含有null,该列就会从
索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。任何
在where子句中使用is null或is not null的语句优化器是不允
许使用索引的。
3、IN和EXISTS
EXISTS要远比IN的效率高。里面关系到full table scan和range scan。几乎将所
有的IN操作符子查询改写为使用EXISTS的子查询。
4、在海量查询时尽量少用格式转换。
5、当在SQL SERVER 2000中,如果存储过程只有一个参数,并且是OUTPUT类型的,必
须在调用这个存储过程的时候给这个参数一个初始的值,否则
会出现调用错误。
6、ORDER BY和GROPU BY
使用ORDER BY和GROUP BY短语,任何一种索引都有助于SELECT的性能提高。注意
如果索引列里面有NULL值,Optimizer将无法优化。
7、任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时
要尽可能将操作移至等号右边。
8、IN、OR子句常会使用工作表,使索引失效。如果不产生大量重复值,可以考虑把
子句拆开。拆开的子句中应该包含索引。
9、SET SHOWPLAN_ALL ON 查看执行方案。DBCC检查数据库数据完整性。
DBCC(DataBase Consistency Checker)是一组用于验证 SQL Server 数据
库完整性的程序。
10、慎用游标
在某些必须使用游标的场合,可考虑将符合条件的数据行转入临时表中,再对临
时表定义游标进行操作,这样可使性能得到明显提高。
总结:所谓优化即WHERE子句利用了索引,不可优化即发生了表扫描或额外开销。经
验显示,SQL Server性能的最大改进得益于逻辑的数据库设计、
索引设计和查询设计方面。反过来说,最大的性能问题常常是由其中这些相同方面中
的不足引起的。其实SQL优化的实质就是在结果正确的前提下,
用优化器可以识别的语句,充份利用索引,减少表扫描的I/O次数,尽量避免表搜索
的发生。其实SQL的性能优化是一个复杂的过程,上述这些只是
在应用层次的一种体现,深入研究还会涉及数据库层的资源配置、网络层的流量控制
以及操作系统层的总体设计。
先闭上左眼,用右眼看;
再闭上右眼,用左眼看;
哪个舒服那个速度快!
还看不出来,就闭上双眼。
hehe!
select getdate()selct * form where ````````select getdate()
这2个getdate的时间差就是你的速度,基本误差不过0.1毫秒 很简单
简单的问题复杂话了你们
declare @t1 datetime,@t2 datetimeset @t1=getdate()select............./*你的查询语句*/set @t2=getdate()select datediff(ms,@t1,@t2)
这个简单办法可以吗?
select * from a inner join b where a.c=1
速度差很多,请自己测试
SET STATISTICS PROFILE ON
SET STATISTICS IO ON
SET STATISTICS TIME ON
GO
--你的SQL脚本
GO
SET STATISTICS PROFILE OFF
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
2. SET SHOWPLAN_ALL ON;
GO
--你的SQL脚本
GO
SET SHOWPLAN_ALL OFF;