我在SQL Server 2005的单个实例上有多个数据库。我在一个数据库上创建了一个同义词来访问另一个数据库上的表,在编写查询时,我想使用特定的索引,但是,在评估执行计划时,它似乎没有使用它。如果我编写查询以显式访问数据库,它可以工作,但我似乎无法使用同义词使其工作。例如:
select *
from testdb..testtable with (index(testindex))
|--Nested Loops(Inner Join, OUTER REFERENCES:([testdb].[dbo].[testtable].[id]))
|--Index Scan(OBJECT:([testdb].[dbo].[testtable].[testindex]))
|--Clustered Index Seek(OBJECT:([testdb].[dbo].[testtable].[PK_testtable]), SEEK:([testdb].[dbo].[testtable].[id]=[testdb].[dbo].[testtable].[id]) LOOKUP ORDERED FORWARD)
不会产生与
相同的执行计划select *
from testdb_synonym with (index(testindex))
|--Clustered Index Scan(OBJECT:([testdb].[dbo].[testtable].[PK_testtable]))
这是同义词的限制还是我需要做些什么才能让它发挥作用?
答案 0 :(得分:5)
这是Microsoft已修复的错误:请参阅MS KB 963684
在Microsoft SQL Server 2005中,您 创建表的同义词。你跑 对同义词的查询。查询 使用INDEX优化器提示强制 一个索引。如果检查执行 为查询生成的计划, 你可能会发现执行计划的确如此 不要使用强制索引。
答案 1 :(得分:1)
我测试了同样的事情,似乎查询优化器在通过同义词完成时忽略了该提示。详细信息是我针对具有索引提示的任意表执行select *以使用非聚集索引。没有同义词,它会执行书签查找/嵌套循环连接。有了它,它会进行表扫描。由于创建同义词语法没有选项,我只能假设忽略索引提示。 BOL中没有详细说明原因。我会把它作为一个“特征”。
答案 2 :(得分:1)
WITH INDEX
提示。
CREATE SYNONYM syn_master FOR master
SELECT *
FROM syn_master WITH (INDEX (wow_i_can_write_everything_here))
尽管我的架构中没有名为wow_i_can_write_everything_here
的索引,但编译并运行正常。
答案 3 :(得分:0)
你需要提示吗?如果可能的话,MS建议是避免索引提示,因为这可能使更优化的计划无效。即使它今天已经优化,但由于数据负载等原因,明天可能效率低下。
我尝试在SQL Server 2008中使用没有提示的同义词,并使用同义词和完全限定名称(database.schema.table)获得相同的执行计划。
我甚至尝试将同义词与索引提示一起使用,并成功强制进行非聚集索引查找(以及键查找以获取其余数据),并获得具有完全限定名称的相同执行计划。
您的统计数据是否已更新?您是否有选择性索引或SQL服务器认为使用表扫描更有效。