对于这个题目,个人持如下观点:1.如果仅仅是为了利用上索引,则应该强制指定索引: select * from 职工表 with(index(索引名)) where 年龄>45 or 工资<10002.如果是为了优化,则要考虑以下情况: a.union 的方法可能可以利用上索引,也可能用不上索引,这样的写法受SQL内部处理的影响 同时union的方法存在这样一个问题: 由于在描述题目的时候,并没有说明职工表是否有不重复的记录 所以,如果职工表中如果记录本身有满足查询条件的重复记录的时候,则查询出的结果是错误的 b.union all的写法就不说了,一般都会产生重复记录 c.对于>=和<=的写法,个人觉得没有什么特别的根据,而且,也没有说明年龄和工资字段的数据类型 所以,如果工资有小数的话,显然不能用<=3.不利用索引,效率不一下比利用索引低所以这道题不严谨 如果是为了考你索引的使用,应该是用强制指定索引 如果是为了考你优化,则可以这样认为,查询方法不用改,由sql内部自己优化去
--关于这道题,我的测试环境是这样建立的--测试表 if objectproperty(object_id(N'职工表'),'isusertable') is not null drop table 职工表create table 职工表( id int identity, name nvarchar(10), 年龄 int, 工资 decimal(10,2)) create index idx_职工表_年龄_工资 on 职工表(年龄,工资) go--测试数据 insert 职工表 select right(newid(),10),a.colid+43 ,a.colid+b.colid*rand()*50+980 from syscolumns a,syscolumns b go
--大家可以分别测试一下,这三种写法的效率select * from 职工表 where 年龄>45 or 工资<1000select * from 职工表 with(index(idx_职工表_年龄_工资)) where 年龄>45 or 工资<1000select * from 职工表 where 年龄>45 union select * from 职工表 where 工资<1000
--以下是我的机器上运行时间(P41.7G) --1.运行时间:2:50 再一次运行: 2:08 select * from 职工表 where 年龄>45 or 工资<1000--2.运行时间:3:14 select * from 职工表 with(index(idx_职工表_年龄_工资)) where 年龄>45 or 工资<1000--3.运行时间:3:10 select * from 职工表 where 年龄>45 union select * from 职工表 where 工资<1000
to (邹建): <1> select * from 职工表 with(index(索引名)) where 年龄>45 or 工资<1000 此语句是 T-sql的 写法还是 sql92 的写法?我不大清楚,望告知。 如果是 T-sql 则行不通,因为不是考 MS_sql <2>职工表有 [职工编号] 主键,所以是无重复纪录的
楼主说:已在职工表上的年龄、工资字段上做了索引。 疑问:您说的所做的索引是在年龄、工资字段上做的复合索引,还是在这两个字段上分别做索引。 如果是复合的:那么 select * from 职工表 where 年龄>45 能利用上索引。 而 select * from 职工表 where 工资<1000利用不上索引。 如果是后者:那么 select * from 职工表 where 年龄>45 union select * from 职工表 where 工资<1000 能够提高效率。
--大家可以分别测试一下,这三种写法的效率select * from 职工表 where 年龄>45 or 工资<1000select * from 职工表 with(index(idx_职工表_年龄_工资)) where 年龄>45 or 工资<1000select * from 职工表 where 年龄>45 union select * from 职工表 where 工资<1000我测试一下,每次都是第一种写法的时间最短,为什么前面回答的几位老大的答案都是用union呢??? 谁解释一下!!!
根据所用的索引 应该用UNION ALL 呀
select * from 职工表 where 年龄>45 or 工资<1000 6秒 select * from 职工表 with(index(idx_职工表_年龄_工资)) where 年龄>45 or 工资<1000 5秒 select * from 职工表 where 年龄>45 union select * from 职工表 where 工资<1000 8秒
怎么周大哥的方案每人测的都不一样啊,第一次查 select * from 职工表 where 年龄>45 or 工资<1000 --4秒 select * from 职工表 with(index(idx_职工表_年龄_工资)) where 年龄>45 or 工资<1000 --2秒 select * from 职工表 where 年龄>45 union select * from 职工表 where 工资<1000 --2秒第二、三次查 select * from 职工表 where 年龄>45 or 工资<1000 --3秒 select * from 职工表 with(index(idx_职工表_年龄_工资)) where 年龄>45 or 工资<1000 --3秒 select * from 职工表 where 年龄>45 union select * from 职工表 where 工资<1000 --2秒 我测得的结果是:Union快一点
大家看看这个sqlSELECT * FROM (SELECT * FROM 职工表 WHERE 年龄>=46) A WHERE A.工资<=999.99具体是年龄field放在里面还是工资field放在里面要看数据的分布,如果条件过滤后数据量最小则应该放在里面的where语句中 union 会过滤重复记录,但是性能较低,需要排序所有数据再使用算法过滤 union all不会过滤重复记录
如果有的职工年龄>45 和 工资<1000
使用你的语句就会出现重复的纪录
union ALL
select * from 职工表 where 工资<1000
union all 会出现重复的.
union的效率其实也不高,另外用>=代替比较好吧
select * from 职工表 where 年龄>=46
union
select * from 职工表 where 工资<=999.99
union all
select * from 职工表 where 工资<1000
union
select * from 职工表 where 工资<1000
union
select * from 职工表 where 工资<=1001--根据工资的数据类型而变
用or也不会产重复记录的!
select * from 职工表 with(index(索引名)) where 年龄>45 or 工资<10002.如果是为了优化,则要考虑以下情况:
a.union 的方法可能可以利用上索引,也可能用不上索引,这样的写法受SQL内部处理的影响
同时union的方法存在这样一个问题:
由于在描述题目的时候,并没有说明职工表是否有不重复的记录
所以,如果职工表中如果记录本身有满足查询条件的重复记录的时候,则查询出的结果是错误的 b.union all的写法就不说了,一般都会产生重复记录 c.对于>=和<=的写法,个人觉得没有什么特别的根据,而且,也没有说明年龄和工资字段的数据类型
所以,如果工资有小数的话,显然不能用<=3.不利用索引,效率不一下比利用索引低所以这道题不严谨
如果是为了考你索引的使用,应该是用强制指定索引
如果是为了考你优化,则可以这样认为,查询方法不用改,由sql内部自己优化去
if objectproperty(object_id(N'职工表'),'isusertable') is not null
drop table 职工表create table 职工表(
id int identity,
name nvarchar(10),
年龄 int,
工资 decimal(10,2))
create index idx_职工表_年龄_工资 on 职工表(年龄,工资)
go--测试数据
insert 职工表 select right(newid(),10),a.colid+43
,a.colid+b.colid*rand()*50+980
from syscolumns a,syscolumns b
go
union
select * from 职工表 where 工资<1000
--1.运行时间:2:50 再一次运行: 2:08
select * from 职工表 where 年龄>45 or 工资<1000--2.运行时间:3:14
select * from 职工表 with(index(idx_职工表_年龄_工资)) where 年龄>45 or 工资<1000--3.运行时间:3:10
select * from 职工表 where 年龄>45
union
select * from 职工表 where 工资<1000
<1> select * from 职工表 with(index(索引名)) where 年龄>45 or 工资<1000
此语句是 T-sql的 写法还是 sql92 的写法?我不大清楚,望告知。 如果是 T-sql 则行不通,因为不是考 MS_sql <2>职工表有 [职工编号] 主键,所以是无重复纪录的
职工表有 [职工编号] 主键,这是你事前没有说清楚的,如果是sql server数据库,用union可以,但也不能完全保证利用上索引
疑问:您说的所做的索引是在年龄、工资字段上做的复合索引,还是在这两个字段上分别做索引。
如果是复合的:那么
select * from 职工表 where 年龄>45 能利用上索引。
而
select * from 职工表 where 工资<1000利用不上索引。
如果是后者:那么
select * from 职工表 where 年龄>45
union
select * from 职工表 where 工资<1000
能够提高效率。
union
select * from 职工表 where 工资<1000我测试一下,每次都是第一种写法的时间最短,为什么前面回答的几位老大的答案都是用union呢???
谁解释一下!!!
应该用UNION ALL 呀
6秒
select * from 职工表 with(index(idx_职工表_年龄_工资)) where 年龄>45 or 工资<1000
5秒
select * from 职工表 where 年龄>45
union
select * from 职工表 where 工资<1000
8秒
select * from 职工表 where 年龄>45 or 工资<1000
--4秒
select * from 职工表 with(index(idx_职工表_年龄_工资)) where 年龄>45 or 工资<1000
--2秒
select * from 职工表 where 年龄>45
union
select * from 职工表 where 工资<1000
--2秒第二、三次查
select * from 职工表 where 年龄>45 or 工资<1000
--3秒
select * from 职工表 with(index(idx_职工表_年龄_工资)) where 年龄>45 or 工资<1000
--3秒
select * from 职工表 where 年龄>45
union
select * from 职工表 where 工资<1000
--2秒
我测得的结果是:Union快一点
WHERE A.工资<=999.99具体是年龄field放在里面还是工资field放在里面要看数据的分布,如果条件过滤后数据量最小则应该放在里面的where语句中
union 会过滤重复记录,但是性能较低,需要排序所有数据再使用算法过滤
union all不会过滤重复记录