【发布时间】:2018-06-21 09:52:50
【问题描述】:
我的基础表如下所示:
----------------------------
| Id | Type |Value |
----------------------------
| 1 |Name |Michael |
| 1 |Age |20 |
| 2 |Name |John |
| 3 |Name |Smith |
| 5 |Age |25 |
----------------------------
我在“类型”、“值”列上创建了一个索引。 (编辑:基于 cmets 的附加值)
我探索了几个选项来给我一个透视图。像这样的:
------------------------
| Id |Name |Age |
------------------------
| 1 |Michael|20 |
| 2 |John | |
| 3 |Smith |25 |
------------------------
Sql1(使用数据透视):
CREATE View vw AS
SELECT
ID
NAME,
AGE
FROM
(
SELECT
ID,
TYPE,
VALUE
FROM table
) AS SourceTable
PIVOT
(
MAX(VALUE)
FOR TYPE IN ([Name],[Age])
) piv
Sql2(条件聚合)
CREATE View vw AS
SELECT
Id,
[Name]= MAX(CASE WHEN [TYPE]='Name' THEN VALUE END),
[Age] = MAX(CASE WHEN [TYPE]='Age' THEN VALUE END)
FROM
table
GROUP BY
Id
当我运行如下查询时:
SELECT * FROM vw WHERE vw.Name = 'Michael'
我看到执行计划正在对主键 (id) 使用索引扫描。 有什么方法可以使它工作,以便它使用我在“类型”列上创建的索引?
编辑: 我本身没有平面表的原因是因为对于每个 id,我最终可能会得到大约 100 个字段。并且应该可以根据任何字段进行搜索。因此,如果我能够让系统使用 (Type, Value) 上的索引,我希望这样的设计可能会有所帮助
【问题讨论】:
-
在您的示例中,ID 不是主键,因为 ID 是重复的。 Sql1 查询也不会产生相同的结果。你为 Type 建立了什么样的索引?
-
对不起,我错过了。我的主键是 (ID, Type) 组合。至于Type上的其他索引,它是Non-Clustered Index。
-
既然你没有任何过滤条件,你为什么期望一个索引被使用呢?聚簇索引扫描是您所需要的,也是您得到的。
-
@Alex,没有任何过滤条件是什么意思。我的过滤条件适用于新的 Pivot 列(WHERE vw.Name = 'Michael')。基于上述评论,我为(类型,值)添加了一个非聚集索引。我希望在添加子句 WHERE vw.Name = 'Michael' 时使用它而不是主键扫描
-
尝试在视图上创建索引,而不是在表上
标签: sql sql-server sql-server-2008 pivot