(询问:在sql服务器中调优 - 视图。抱歉,我需要查看我的帖子)。
我需要在连接中添加提示(在执行连接时强制使用 ID 上的索引),和选择(强制对 where 子句的名称使用索引),如本文中提到的最后一个查询。我不知道正确连接的正确语法是什么(用于调整),以及力索引的正确语法是什么,当我从视图中选择时,子句将使用它。
我在 sql server 2012 中创建了一个视图,例如:
create myview as
select mytable2.name
from mytable1 t1
join myTable2 t2
on t1.id = t2.id
我希望连接表1和表2将具有正确的索引(id),但是当我这样做时:
select * from myview
where name = 'abcd'
我希望最后一个选择将带有"名称"列的索引。
正如我所描述的,带有提示(调优)的sql服务器中的正确语法是什么,可以最好地运行?
我想强制仅出于连接目的使用索引(列 = id),并在执行以下操作时强制使用索引名称:
select name from myview
where name = 'abcd'.
类似的东西
create myview as
select mytable2.name
/* index hint name on column name */
from mytable1 t1
join myTable2 t2
/* index hint name on column id - just for join */
on t1.id = t2.id
我不想强迫使用视图的最终用户在执行视图时添加提示 - 只需将视图作为他的视图,并带有适当的索引提示即可。(或者,如果不可能 - 我该怎么做)。
请提供样品。
我有这么一个简单的观点(无论表格基于什么......对于我工作的公司来说,这是非常明确的。这是Microsoft动态AX 2012 +一些额外的表)。
create view [dbo].[splSqlAltItemsView]
as
select i_orig.dataareaid, id_orig.inventsiteid, i_orig.itemid, i_alt.itemid altItemId,
orig_item.minTollerance, orig_item.maxTollerance
from
(
select orig_item.recid,
c_grade.value as grade,
c_materialFamily.value as MaterialFamily,
c_shape.value as shape,
c_thickness.value as thickness,
convert(real, isnull(c_minTollerance.value, 0.00)) as minTollerance,
convert(real, isnull(c_maxTollerance.value, 0.00)) as maxTollerance
from
(select e0.recid
from ECORESPRODUCT e0
where e0.recid in
(
select productid
from CMAPRODUCTATTRIBUTEVALUES c0
where name in ('Grade', 'Material Family', 'Shape', 'Thickness')
and productid > 0
group by productid
having count(1) = 4
)) orig_item
join CMAPRODUCTATTRIBUTEVALUES c_grade
on c_grade.PRODUCTID = orig_item.RECID
and c_grade.name = 'Grade'
join CMAPRODUCTATTRIBUTEVALUES c_materialFamily
on c_materialFamily.PRODUCTID = orig_item.RECID
and c_materialFamily.name = 'Material Family'
join CMAPRODUCTATTRIBUTEVALUES c_shape
on c_shape.PRODUCTID = orig_item.RECID
and c_shape.name = 'Shape'
join CMAPRODUCTATTRIBUTEVALUES c_thickness
on c_thickness.PRODUCTID = orig_item.RECID
and c_thickness.name = 'Thickness'
left join CMAPRODUCTATTRIBUTEVALUES c_minTollerance
on c_minTollerance.PRODUCTID = orig_item.RECID
and c_minTollerance.name = 'Min Tollerance'
left join CMAPRODUCTATTRIBUTEVALUES c_maxTollerance
on c_minTollerance.PRODUCTID = orig_item.RECID
and c_minTollerance.name = 'Max Tollerance'
) orig_item
join
(select alt_item.recid,
c_grade.value as grade,
c_materialFamily.value as MaterialFamily,
c_shape.value as shape,
c_thickness.value as thickness,
convert(real, isnull(c_minTollerance.value, 0.00)) as minTollerance,
convert(real, isnull(c_maxTollerance.value, 0.00)) as maxTollerance
from
(select e0.recid
from ECORESPRODUCT e0
where e0.recid in
(
select productid
from CMAPRODUCTATTRIBUTEVALUES c0
where name in ('Grade', 'Material Family', 'Shape', 'Thickness')
and productid > 0
group by productid
having count(1) = 4
)) alt_item
join CMAPRODUCTATTRIBUTEVALUES c_grade
on c_grade.PRODUCTID = alt_item.RECID
and c_grade.name = 'Grade'
join CMAPRODUCTATTRIBUTEVALUES c_materialFamily
on c_materialFamily.PRODUCTID = alt_item.RECID
and c_materialFamily.name = 'Material Family'
join CMAPRODUCTATTRIBUTEVALUES c_shape
on c_shape.PRODUCTID = alt_item.RECID
and c_shape.name = 'Shape'
join CMAPRODUCTATTRIBUTEVALUES c_thickness
on c_thickness.PRODUCTID = alt_item.RECID
and c_thickness.name = 'Thickness'
left join CMAPRODUCTATTRIBUTEVALUES c_minTollerance
on c_minTollerance.PRODUCTID = alt_item.RECID
and c_minTollerance.name = 'Min Tollerance'
left join CMAPRODUCTATTRIBUTEVALUES c_maxTollerance
on c_minTollerance.PRODUCTID = alt_item.RECID
and c_minTollerance.name = 'Max Tollerance'
) alt_item
on alt_item.grade = orig_item.grade
and alt_item.MaterialFamily = orig_item.MaterialFamily
and alt_item.shape = orig_item.shape
and (alt_item.thickness between orig_item.thickness - orig_item.minTollerance and orig_item.thickness + orig_item.maxTollerance or
orig_item.thickness between alt_item.thickness - alt_item.minTollerance and alt_item.thickness + alt_item.maxTollerance)
join inventtable i_orig
on i_orig.product = orig_item.recid
join InventItemInventSetup is_orig
on is_orig.dataareaid = i_orig.dataareaid
and is_orig.itemid = i_orig.itemid
and is_orig.inventdimid = 'AllBlank'
join InventDim id_orig
on id_orig.DATAAREAID = is_orig.DATAAREAID
and id_orig.inventdimid = is_orig.inventdimiddefault
join inventtable i_alt
on i_alt.product = alt_item.recid
and i_alt.DATAAREAID = i_orig.DATAAREAID
join InventItemInventSetup is_alt
on is_alt.dataareaid = i_alt.dataareaid
and is_alt.itemid = i_alt.itemid
and is_alt.inventdimid = 'AllBlank'
join InventDim id_alt
on id_alt.DATAAREAID = is_alt.DATAAREAID
and id_alt.inventdimid = is_alt.inventdimiddefault
and id_alt.inventsiteid = id_orig.inventsiteid
当我这样做时:
select * from splSqlAltItemsView
where itemid = '12345'
有很多时间很耗时,甚至发明表也有关于itemid的索引。
当我这样做时:
select * from splSqlAltItemsView
视图运行数秒。
通常不建议在 SQL Server 中使用提示,因为查询优化器旨在根据统计信息、索引和其他因素选择最有效的执行计划。但是,在极少数情况下,使用提示可能有助于微调性能。如果您知道优化程序没有为查询选择最佳索引,则提示可能很有用。但是,请务必注意,使用提示可能存在风险,因为随着数据更改和索引的添加或删除,提示可能会随着时间的推移而过时或不相关。
create myview as
select mytable2.name
from mytable1 t1 WITH (INDEX(index_name1))
join myTable2 t2
WITH (INDEX(index_name2))
on t1.id = t2.id
在此查询中,WITH (INDEX(index_name))
提示用于指定要用于每个表的索引。请注意,索引名称必须与表上现有索引的名称匹配,否则将忽略提示。
谨慎使用提示,并全面测试其对查询性能的影响。通常,依靠查询优化器来选择最佳执行计划是个好主意,但在极少数情况下,提示可能是优化查询性能的有用工具。