帮我解释一下SQL语句

Hero2018 2008-06-30 05:27:32
--返回50条
Select [ID] From [Company] Where [Name] Like '电子%' --0秒
Select [ID],[Name] From [Company] Where [Name] Like '电子%' --0秒
Select [ID],[Name],[Address] From [Company] Where [Name] Like '电子%' -- 22 秒

--返回30条
Select [ID] From [Company] Where [Address] Like '电子%' -- 0 秒
Select [ID],[Address] From [Company] Where [Address] Like '电子%' -- 0 秒
Select [ID],[Address],[Name] From [Company] Where [Address] Like '电子%' -- 20 秒

ID 主键,聚集索引
Name 非聚集索引
Address 非聚集索引

Select [ID],[Name],[Address] From [Company] Where [Name] Like '电子%'
怎么会要这么长时间,很奇怪。好象没有用索引。Like '关键字%'因该会用索引的。
...全文
139 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Hero2018 2008-07-01
  • 打赏
  • 举报
回复
14楼的话我明白了。
-------------
Select Top 300 [ID],[Name],[Address] From [Company] Where Left([Name],2)='电子' -- 1秒
索引扫描 + 聚集索引查找。
[索引扫描]比[索引查找]慢,这个现在懂了。Left 用[索引扫描], Like 'x%' 可能会用[索引查找]


但是不明白
Select [ID],[Name],[Address] From [Company] Where [Name] Like '电子%' -- 20秒
聚集索引扫描。

Select [ID],[Name],[Address] From [Company] Where [Name] Like '电子工业学%' -- 0秒
索引查找 + 聚集索引查找。
不明白 SQL Server 如何分析的,所以我认为 Like 'x%' 有根据长度来决定是否用索引查找的因素。
你怎么想的。







nzperfect 2008-07-01
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 Hero2018 的回复:]
一方面要看sql server是否能使之转化为符合SARGs:能。
另一方面就是要看所查数据数量占总表数量的比率:比率小。
sql server 为什么不用索引查找,而用聚集索引扫描。
还是不明白,是那里出错了?
如果说比率高不用,可能理解,难道sql server 认为它比率高,这好象不可能。
[/Quote]

聚集索引是表的特理存储,非聚集索引的叶子层存放着聚集索引的键值(可以理解为id),因为叶子层没有Address列,所以要通过聚集索引找到Address列值。
所以这个过程一部分是利用非聚集索引找到所有的like '电子%'的数据,一部分是利用聚集索引找address.
nzperfect 2008-07-01
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 Hero2018 的回复:]
11楼
----
Select [ID],[Name],[Address] From [Company] Where [Name] Like '电子%' -- 20秒
我的理解是
1.索引查找,[Name]的索引页,找到符合要求的。
2.从[Name]的索引页中取得所有符合要求的[ID]。
3.通过聚集索引查找出这些[ID]相应的[Address]。
[/Quote]

是这样的。
Hero2018 2008-07-01
  • 打赏
  • 举报
回复
11楼
----
Select [ID],[Name],[Address] From [Company] Where [Name] Like '电子%' -- 20秒
我的理解是
1.索引查找,[Name]的索引页,找到符合要求的。
2.从[Name]的索引页中取得所有符合要求的[ID]。
3.通过聚集索引查找出这些[ID]相应的[Address]。


一方面要看sql server是否能使之转化为符合SARGs:能。
另一方面就是要看所查数据数量占总表数量的比率:比率小。
sql server 为什么不用索引查找,而用聚集索引扫描。
还是不明白,是那里出错了?
如果说比率高不用,可能理解,难道sql server 认为它比率高,这好象不可能。

nzperfect 2008-07-01
  • 打赏
  • 举报
回复
可以使用并不是说必定使用.

索引查找是水平查找,可以直接定位;
索引扫描是垂直扫描,无法直接定位,需要扫描索引叶子层所有数据。

用sql server的思维去写代码,不是用自己的思维去写代码。

sql server的最优华是按成本去计算的,我在5楼已经解释的很清楚了。

索引索引索引,你要明白他的存储方式再行。
Hero2018 2008-07-01
  • 打赏
  • 举报
回复
谢谢1楼的指点。
------------

大概知道点原因了。
SQL Server 2005
Company 表有200万条数据。
以“电子”开头有49条
以“电子工业”开头有42条

1.Select Top 300 [ID],[Name] From [Company] Where 1=1 And [Name] Like '电子%' -- 0秒
索引查找。[Name]索引被使用。

2.Select Top 300 [ID],[Name],[Address] From [Company] Where [Name] Like '电子%' -- 20秒
聚集索引扫描。[Name]索引没用使用。

3.Select Top 300 [ID],[Name],[Address] From [Company] Where Left([Name],2)='电子' -- 1秒
索引扫描 + 聚集索引查找。[Name]索引被使用。

4.Select Top 300 [ID],[Name],[Address] From [Company] Where [Name] Like '电子工业%' -- 0秒
索引查找 + 聚集索引查找。[Name]索引被使用。


5楼、8楼
-------
5.Select Top 300 [ID],[Name],[Address] From [Company] Where [Tel] Like '88%' -- 74 毫秒
聚集索引扫描。

6.Select Top 300 [ID],[Name],[Address] From [Company] Where [Tel] Like '888%' -- 84 毫秒
聚集索引扫描。

7.Select Top 300 [ID],[Name],[Address] From [Company] Where [Tel] Like '8888%' -- 86 毫秒
索引查找 + 聚集索引查找。

Select [ID],[Name],[Address] From [Company] Where [Name] Like '电子%' -- 20秒
Select [ID],[Name],[Address] From [Company] Where [Name] Like '电子工%' -- 20秒
Select [ID],[Name],[Address] From [Company] Where [Name] Like '电子工业%' -- 0秒
Select [ID],[Name],[Address] From [Company] Where [Name] Like '电子工业学%' -- 0秒

like 'xx%'可以有效使用索引
这可能不一定。会和字符长度有关。
当搜索字大于3字节时会用索引查找,否则就不用索引。
当索引页中有查询的字段时,一定会用索引查找,如 1。
你可以自已试一试,可能我理解有错误。



Left 就更奇怪了。
Tel 非聚集索引

Select Count(*) From [Company] Where Left([Tel],1)='1' -- 3522条
Select Count(*) From [Company] Where Left([Tel],1)='8' -- 646365条

1.Select Top 300 [ID],[Name],[Address] From [Company] Where Left([Tel],1)='1' - 0秒
索引扫描 + 聚集索引查找。使用索引。

2.Select Top 300 [ID],[Name],[Address] From [Company] Where Left([Tel],1)='8' - 0秒
聚集索引扫描。不使用索引。

[Quote=引用 7 楼 perfectaction 的回复:]
是否使用索引,一方面要看sql server是否能使之转化为符合SARGs,另一方面就是要看所查数据数量占总表数量的比率。
[/Quote]
好象是这样。


3.Select Top 300 [ID],[Name],[Address] From [Company] Where Left([Tel],3)='888' - 1秒
索引扫描 + 聚集索引查找。

4.Select Top 300 [ID],[Name],[Address] From [Company] Where Left([Name],1)='电' -- 1 秒
索引扫描 + 聚集索引查找。

5.Select Top 300 [ID],[Name],[Address] From [Company] Where Left([Name],2)='电子' -- 1 秒
索引扫描 + 聚集索引查找。

感觉 Left 比 Like 'x%' 智能一些,Left 会判断比率。
以前一直认为 Left 和 Like 'x%' 都会用索引,现在觉的它们都是动态的,不一定会用索引。

有不同看法,可以讨论一下。
nzperfect 2008-07-01
  • 打赏
  • 举报
回复
这个条件[Name] Like '电子工业学%'
比[Name] Like '电子%'
占总表记录的比例要小,所以sql server认为它用索引查找 + 聚集索引查找比用聚集索引扫描成本更低。

至于sql server到底如何来搞清楚哪个成本最低,估计要微软来说了,说说他是怎么个算法。
nzperfect 2008-06-30
  • 打赏
  • 举报
回复
像substring left right charindex等等操作字符串的函数,都会使索引失效
这些都是无法有效使用索引的。
nzperfect 2008-06-30
  • 打赏
  • 举报
回复
再说一遍:
like 'xx'可以有效使用索引
like 'xx%'可以有效使用索引
like '%xx%'不能有效使用索引
nzperfect 2008-06-30
  • 打赏
  • 举报
回复
是否使用索引,一方面要看sql server是否能使之转化为符合SARGs,另一方面就是要看所查数据数量占总表数量的比率。
tianhuo_soft 2008-06-30
  • 打赏
  • 举报
回复

有一次technet 微软的工程说的 like会失去索引的价值
nzperfect 2008-06-30
  • 打赏
  • 举报
回复
like '电子%' 是可以有效使用索引的。
substring是肯定不能有效使用索引的。

楼主只所以有这个问题,原因有两种:
一种是以"电子"开头的数据占总记录的比率过多,使用索引成本不一定比全表扫描快。
另一种原因是正常的,那就是:
like '电子%' 使用到了Name 非聚集索引,这时如果是Select [ID],[Name]或是Select [ID]或是Select [name]都会很快。
但是如果再多select一个其它字段,比如Select [ID],[Name],[Address],这样的话,先前通过索引Name找到的数据,会根据索引叶子层每条数据对应的聚集索引键(ID)再去"ID 主键,聚集索引 "寻找Address字段值,所以这时就要花费多余的时间了。
这就是为什么
Select [ID] From [Company] Where [Name] Like '电子%' --0秒
Select [ID],[Name] From [Company] Where [Name] Like '电子%' --0秒
比较快,而
Select [ID],[Name],[Address] From [Company] Where [Name] Like '电子%' -- 22 秒
就比较慢一点的原因。
hery2002 2008-06-30
  • 打赏
  • 举报
回复
谣传like会让索引失效的,
你的语句可以改改,
--try
Select [ID],[Name],[Address] From [Company] Where left([Name],2)='电子'
tianhuo_soft 2008-06-30
  • 打赏
  • 举报
回复
我宁愿使用


where substring([Name],1,2)='电子' 也不会使用Where [Name] Like '电子%' --
因为一旦使用like 那么索引就失去了价值

viptiger 2008-06-30
  • 打赏
  • 举报
回复
如果你表中的记录 相当庞大,按照你提供的条件基本不会用到 非聚集索引,基本都应该根据[ID]聚集索引查找

查询的字段越多,速度相应也会降低。

根据你的现象看,每次都是在查询字段多于 限制条件的时候出现问题


可能的原因很多

建议 见谅不要用LIKE,尽量减少要查询的字段
懒牛科技 2008-06-30
  • 打赏
  • 举报
回复
按下Ctrl+M 然后执行.看看是否用到索引!

22,210

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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