sql 语句优化 【只求答案,分不是问题】

风2013 2012-01-06 03:54:15
select * from View_ShopMedicine where exists ( select MedicineId,ShopId,Standard from ShopMedicine sm where sm.MedicineId = View_ShopMedicine.MedicineId  and sm.ShopId = View_ShopMedicine.ShopId and sm.Standard=View_ShopMedicine.ShopMedicineStandard group by MedicineId,ShopId,Standard having(COUNT(*)) >1)


后面接的and比较多.........只要时间都用在这个上面了 View_ShopMedicine 为视图,你也可以当做是一个表
...全文
132 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
风2013 2012-01-06
  • 打赏
  • 举报
回复
辛苦各位了,回帖都有分
风2013 2012-01-06
  • 打赏
  • 举报
回复
我还是整理下,重新弄个帖子吧
风2013 2012-01-06
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 maco_wang 的回复:]

SQL code

if object_id('[View_ShopMedicine]') is not null drop table [View_ShopMedicine]
create table [View_ShopMedicine] (MedicineId int,ShopId int,ShopMedicineStandard int)
insert into [View_ShopM……
[/Quote]
是的
libian333 2012-01-06
  • 打赏
  • 举报
回复
不知道是哪位仁兄博客里的,帖出来给你参考下。

我们先讨论IN和EXISTS。
select * from t1 where x in ( select y from t2 )
事实上可以理解为:
select *
from t1, ( select distinct y from t2 ) t2
where t1.x = t2.y;
——如果你有一定的SQL优化经验,从这句很自然的可以想到t2绝对不能是个大表,因为需要对t2进行全表的“唯一排序”,如果t2很大这个排序的性能是不可忍受的。但是t1可以很大,为什么呢?最通俗的理解就是因为t1.x=t2.y可以走索引。但这并不是一个很好的解释。试想,如果t1.x和t2.y都有索引,我们知道索引是种有序的结构,因此t1和t2之间最佳的方案是走merge join。另外,如果t2.y上有索引,对t2的排序性能也有很大提高。
select * from t1 where exists ( select null from t2 where y = x )
可以理解为:
for x in ( select * from t1 )
loop
if ( exists ( select null from t2 where y = x.x )
then
OUTPUT THE RECORD!
end if
end loop
——这个更容易理解,t1永远是个表扫描!因此t1绝对不能是个大表,而t2可以很大,因为y=x.x可以走t2.y的索引。
综合以上对IN/EXISTS的讨论,我们可以得出一个基本通用的结论:IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。


我们要根据实际的情况做相应的优化,不能绝对的说谁的效率高谁的效率低,所有的事都是相对的
叶子 2012-01-06
  • 打赏
  • 举报
回复

if object_id('[View_ShopMedicine]') is not null drop table [View_ShopMedicine]
create table [View_ShopMedicine] (MedicineId int,ShopId int,ShopMedicineStandard int)
insert into [View_ShopMedicine]
select 1,1,1 union all
select 2,2,2 union all
select 3,3,3 union all
select 1,1,1 union all
select 2,2,2 union all
select 4,4,4

if object_id('[ShopMedicine]') is not null drop table [ShopMedicine]
create table [ShopMedicine] (MedicineId int,ShopId int,Standard int)
insert into [ShopMedicine]
select 1,1,1 union all
select 3,3,3 union all
select 1,1,1 union all
select 2,2,2 union all
select 4,4,4


--你原来的写法
select * from
View_ShopMedicine
where exists
(
select MedicineId,ShopId,Standard from ShopMedicine sm
where sm.MedicineId = View_ShopMedicine.MedicineId
and sm.ShopId = View_ShopMedicine.ShopId
and sm.Standard=View_ShopMedicine.ShopMedicineStandard
group by MedicineId,ShopId,Standard having(COUNT(*)) >1
)

--你的结果
/*
MedicineId ShopId ShopMedicineStandard
----------- ----------- --------------------
1 1 1
1 1 1
*/


你原来的写法是这个意思?
dongshanyu 2012-01-06
  • 打赏
  • 举报
回复
=>只能在原有的基础上加条件,所以不能用链接查询,只能加条件查询
select v.*
from View_ShopMedicine v
inner join
(
select sm.MedicineId,sm.ShopId,sm.Standard,COUNT(1) as RdCount
from ShopMedicine sm
where 1 = 1
...
group by sm.MedicineId,sm.ShopId,sm.Standard
) sm on (sm.MedicineId = v.MedicineId and and sm.ShopId = v.ShopId and and sm.Standard = v.ShopMedicineStandard)
where sm.RdCount > 1

...处动态添加你的查询条件,这样不可以吗?
风2013 2012-01-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 hj850126 的回复:]

LZ,你可以把现在的查询结果作为一个表,再对这个表进行查询操作,
[/Quote]
请看 六楼提示
格桑花 2012-01-06
  • 打赏
  • 举报
回复
LZ,你可以把现在的查询结果作为一个表,再对这个表进行查询操作,
风2013 2012-01-06
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dongshanyu 的回复:]

select v.*
from View_ShopMedicine v
inner join
(
select sm.MedicineId,sm.ShopId,sm.Standard,COUNT(1) as RdCount
from ShopMedicine sm
group by sm.MedicineId,sm.ShopId,sm.Standard
) sm on (sm……
[/Quote]
我需要不是这个,由于查询的条件已经很多了,我只能在原有的基础上加条件,所以不能用链接查询,只能加条件查询
风2013 2012-01-06
  • 打赏
  • 举报
回复
视图主要是针对 ShopMedicine 的所有数据,我想查出,MedicineId,ShopId,Standard这三列数据完全相同,且数据条数大于1的数据,即下面sql语句
select MedicineId,ShopId,Standard from ShopMedicine
group by MedicineId,ShopId,Standard having(COUNT(*)) >1

在查询视图中,MedicineId,ShopId,Standard这三列匹配的数据

注:只能添加条件查询,不能两个数据集链接查询
dongshanyu 2012-01-06
  • 打赏
  • 举报
回复
select v.*
from View_ShopMedicine v
inner join
(
select sm.MedicineId,sm.ShopId,sm.Standard,COUNT(1) as RdCount
from ShopMedicine sm
group by sm.MedicineId,sm.ShopId,sm.Standard
) sm on (sm.MedicineId = v.MedicineId and and sm.ShopId = v.ShopId and and sm.Standard = v.ShopMedicineStandard)
where sm.RdCount > 1
叶子 2012-01-06
  • 打赏
  • 举报
回复
View_ShopMedicine 为视图,你也可以当做是一个表

表和视图的索引效率是完全不同的,视图很多情况是不能加索引的。


select * from
View_ShopMedicine
where exists
(
select MedicineId,ShopId,Standard from ShopMedicine sm
where sm.MedicineId = View_ShopMedicine.MedicineId
and sm.ShopId = View_ShopMedicine.ShopId
and sm.Standard=View_ShopMedicine.ShopMedicineStandard
group by MedicineId,ShopId,Standard having(COUNT(*)) >1
)
--不知道你要实现一个什么样的效果
锦上添权 2012-01-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 bdmh 的回复:]

不知你的意图,无法优化,优化不仅仅是看sql的文字,还要根据 业务情况,数据库结构等综合考虑
[/Quote]


顶。。。
bdmh 2012-01-06
  • 打赏
  • 举报
回复
不知你的意图,无法优化,优化不仅仅是看sql的文字,还要根据 业务情况,数据库结构等综合考虑
风2013 2012-01-06
  • 打赏
  • 举报
回复
补充下,数据量比较大

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧