查询静态的具有相当少数据的表应该尽可能地使用替换键(alternate key)而不要使用代理键(surrogate key)作为主键,这样可以获得比较高的性能。潜在的优势要取决于对访问路径或者数据用法的分析。一个表的代理键是由dbMS系统产生的值。对于SQL Server,可能是主键的IDENTITY属性。替换键可能是一个表的CHAR(6)类型的代码列。替换键由一个唯一约束(constraint)来约束。
访问路径或者数据用法分析是指对访问数据库中数据的查询的分析。如果80%的查询是将一个或者几个大表与查询表进行连接,并且有替换键作为WHERE子句的过滤机制,那么该查询表就应该可以使用替换键。
访问路径或者数据用法分析的另一个方面是指这些查询的频率。如果有80%的查询被执行的频率比较高,至少明显地高于另外20%,那么该查询表示也应该使用替换键。
如果查询只有在WHERE字句的过滤机制中有替换键,你可以通过使用下面的方法提升性能:
1.将替换键(数据类型为CHAR(6)的列)作为主键,取消代理键。
2.在查询表中创建一个指向使用CHAR(6)数据类型的大表的外键(foreign key)。
3. 在外键上创建一个索引。
你没有必要通过代理键将一个大表与查询表连接以得到代码列。因为你在大表中已经有代码列作为外键了。这样做的结果是你取消了提升性能的连接,也取消了应该产生一个索引搜索的、被索引的代码列上的过滤字句。
如果大表只有几千行数据,你可能还看不出性能的提升。可能只有当大表的数据大到几百万行时你可以明显地意识到性能的提升。下面就这一段简单的脚本说明了这种情况。
-- 将插入1000行数据做测试
CREATE TABLE LookUp
(lupkey1 int IDENTITY
CONSTRAINT pk_LookUp PRIMARY
KEY,
LuCode CHAR(6) NOT NULL
CONSTRAINT ak_LookUp UNIQUE,
LuCodeDescr VARCHAR(80) NOT NULL
CONSTRAINT dflt_LuCodeDescr
DEFAULT 'UNKNOWN')
GO
--将插入几百万行数据做测试
CREATE TABLE BigTable
(pkey1 INT IDENTITY
CONSTRAINT pk_BigTable PRIMARY
KEY,
lupkey1 int NOT NULL
CONSTRAINT fk_LookUpBigTable
FOREIGN KEY
REFERENCES LookUp (lupkey1),
Col1 int NULL)
GO
SELECT bt.*
FROM BigTablebt
JOIN LookUplu on
bt.lupkey1 = lu.lupkey1
WHERE lu.LuCode = 'TEST1'
GO
DROP TABLE BigTable, LookUp
GO
CREATE TABLE LookUp
(LuCode CHAR(6) NOT NULL
CONSTRAINT pk_LookUp PRIMARY
KEY,
LuCodeDescr VARCHAR(80) NOT NULL
CONSTRAINT dflt_LuCodeDescr
DEFAULT 'UNKNOWN')
GO
CREATE TABLE BigTable
(pkey1 INT IDENTITY
CONSTRAINT pk_BigTable
PRIMARY KEY,
LuCode CHAR(6) NOT NULL
CONSTRAINT fk_LookUpBigTable
FOREIGN KEY
REFERENCES LookUp (LuCode),
Col1 int NULL)
GO
CREATE NONCLUSTERED INDEX idx_fkBigTableLuCode ON BigTAble (LuCode)
GO
SELECT bt.*
FROM BigTablebt
WHERE bt.LuCode = 'TEST1'
GO
DROP TABLE BigTable, LookUp
GO