高效SQL查询之索引(III)
先说说这些误区。所谓“误区”,有一些是新手很容易犯的错误或者很容易忽略的问题,另外一些,则是像“耗子吃了盐会变成蝙蝠”一样,让我们从小就认为是正确的事情。如下:
1、 表上不管用得着用不着,都加个聚集索引。
我们知道,表以两种方式组织物理存储:有聚集索引的“聚集表”;没有聚集索引的“堆”。在聚集表中,数据行按照聚集索引的顺序存储(这也是为啥一张表最多只能有一个聚集索引的原因);堆中,数据行的存储可以认为是不确定的。
在偶《写有效率的 SQL 查询( II )》中曾经介绍过 DB 引擎如何在聚集表中通过非聚集索引查找目标数据:从非聚集索引树根开始 seek ,查找到目标索引行,然后通过索引行上存储的聚集索引键值,爬聚集索引树,并最终通过聚集索引行上的指针拿到目标数据。
但是堆上的非聚集索引存储的不是聚集索引键值,它存储的是指向目标行的指针。也就是说,如果在同样的表是堆,通过非聚集索引 seek 数据将省掉爬聚集索引树的损耗,而可以直接通过非聚集索引行上的行指针直接拿到目标数据。也就是说,在某些情况下,使用堆可以提高系统效率。
这个“某些情况”,就是你的需求,你的系统行为。一般情况下,所有人对要在什么样的字段上创建聚集索引都非常了解;但是不是所有的人都对应该在什么样的系统行为下,不创建聚集索引了解。假设你的表中有字段 col1, col2,col3,col4 等等, col1 、 col2 的分布密度很低。你观察了系统行为,发现一半的查询是 XXXX where col1 = YYYY ,另一半的查询是 XXXX where col2 = YYYY 。这种情况下,使用堆就是更好的选择。
2、 primary key 就是聚集索引。
primary key 上是得有索引,但是这个索引可不见得一定得是聚集索引。尽管语句
create table testPK
(
id int identity ( 1, 1) primary key ,
fname varchar ( 64)
)
会在 id 列上创建聚集索引。当然,一般主键都是聚集索引,但也仅仅是“一般”而已。个人感觉,聚集索引的唯一目标就是数据检索,它应该建在什么字段上,完全由系统行为决定。“一般主键都是聚集索引”也仅仅是因为多数情况下, primary key 字段上建所有更有益于效率而已。
create table testPK
(
相关文档:
今天在配置数据库发布和分发时总是报出现 18483 错误
提示说:错误 18483:未能连接到服务器 "XXX",因为 'distributor_admin'未在该服务器上定义为远程登陆。
我的发布和分发是同一个服务器,"XXX" 为我的机器名,分发数据库是默认的名称,而我在另外一台机器上做时就正常。
1、设置共享复制目录:
......
-- 示例一, 使用证书加密数据.
-- 建立测试数据表
CREATE TABLE tb(ID int IDENTITY (1,1),data varbinary (8000));
GO
-- 建立证书一, 该证书使用数据库主密钥来加密
CREATE CERTIFICATE Cert_Demo1
WITH
SUBJECT = N'cert1 encryption by database master key' ,
START_DATE = ......
先站在应用程序的角度说说它们的不同。
1、 直接拼 SQL
就像大家了解的那样,直接拼 SQL 带来了 SQL 注入攻击,带来了拼时些许的性能损失,但是拼不用添加 SqlParameter ,会少写很多代码——很多人喜欢直接拼,也许就因为这点。这种做法会把你拼好的 SQL 原样直接发送到 DB 服务器去执行。(注意类似 &rdquo ......
我们先看 NestedLoop 和 MergeJoin 的算法(以下为引用,见 RicCC 的《 通往性能优化的天堂 - 地狱 JOIN 方法说明 》 ):
==================================
NestedLoop:
foreach rowA in tableA where tableA.col2=?
{
search rowsB from tableB where tableB.c ......