njb*_*njb 3 sql t-sql sql-server clustered-index
我为视图中使用的查询创建了两个选项,这些选项返回我需要的结果。我需要重写任一选项,以便可以在索引视图中使用它。在视图上创建唯一的聚集索引时,两者均失败。第一个由于LEFT OUTER JOIN而失败,第二个由于子查询而失败。我相信两者都会由于自我加入而失败。
找到“ 创建索引视图”之后,有一大堆无法使用的TSQL语法元素。其中:派生表,UNION,EXCEPT,INTERSECT,子查询,外部或自我联接,TOP,ORDER BY,DISTINCT,MAX ...
CompanyID对于每个唯一查询,查询都应为最大Company。将StatusName在Statuses表还需要显示,而我只补充说,在情况下,它会影响解决方案。当前是INNER JOIN,因此创建索引不会引起问题。
该Companies表的示例,所有3列均为INT:
CompanyID Company Revision
1 1 1
2 1 2
3 2 1
4 2 2
Run Code Online (Sandbox Code Playgroud)
查询应返回:
CompanyID Company Revision
2 1 2
4 2 2
Run Code Online (Sandbox Code Playgroud)
这是我创建的两个选项:
SELECT t1.CompanyID, t1.Company, t1.Revision, Statuses.StatusName
FROM dbo.Companies AS t1
LEFT OUTER JOIN dbo.Companies AS t2
ON t1.Company = t2.Company AND t1.CompanyID < t2.CompanyID
INNER JOIN dbo.Statuses
ON dbo.Statuses.StatusID = t1.StatusID
WHERE t2.Company IS NULL
Run Code Online (Sandbox Code Playgroud)
和另一个:
SELECT t1.CompanyID, t1.Company, t1.Revision, Statuses.StatusName
FROM dbo.Companies AS t1
INNER JOIN dbo.Statuses
ON dbo.Statuses.StatusID = t1.StatusID
WHERE t1.Company NOT IN (SELECT t2.Company from dbo.Companies AS t2 WHERE t1.CompanyID < t2.CompanyID)
Run Code Online (Sandbox Code Playgroud)
因此,我的问题是,是否可以重写任一查询以在索引视图中使用?
我正在使用MS SQL Server 2008 R2和2005。
与其创建排斥视图,不如尝试其他方法:
CREATE VIEW dbo.HighestCompany
AS
SELECT t1.CompanyID, t1.Company, t1.Revision, s.StatusName
FROM dbo.Companies AS t1
INNER JOIN (
SELECT Company, HighestCompany = MAX(CompanyID)
FROM dbo.Companies GROUP BY Company
) AS t2
ON t1.Company = t2.Company
AND t1.CompanyID = t2.HighestCompany -- not sure if CompanyID is unique
INNER JOIN dbo.Statuses AS s
ON s.StatusID = t1.StatusID;
Run Code Online (Sandbox Code Playgroud)
您仍然无法在此上创建索引视图,但是它可能比您当前使用的版本好一些(当然,这取决于多个因素,当然包括公司索引和选择性)。
除此之外,我认为要提高性能,您需要查看基表上的索引策略。为什么您的“公司”表允许多个具有相同名称和不同ID的公司?也许这是问题的一部分,您应该将当前相关的公司存储在单独的表中。
您可以按以下方式进行操作(请记住,我在这里猜测数据类型和最佳索引):
CREATE SCHEMA hold AUTHORIZATION dbo;
GO
CREATE SCHEMA cache AUTHORIZATION dbo;
GO
CREATE TABLE dbo.HighestCompany
(
CompanyID INT,
Company NVARCHAR(255) PRIMARY KEY,
Revision INT,
StatusName NVARCHAR(64)
);
GO
CREATE TABLE cache.HighestCompany
(
CompanyID INT,
Company NVARCHAR(255) PRIMARY KEY,
Revision INT,
StatusName NVARCHAR(64)
);
GO
Run Code Online (Sandbox Code Playgroud)
现在,尽管您经常认为需要刷新此数据,但是您可以运行执行以下操作的作业:
TRUNCATE TABLE cache.HighestCompany;
INSERT cache.HighestCompany(CompanyID, Company, Revision, StatusName)
SELECT t1.CompanyID, t1.Company, t1.Revision, s.StatusName
FROM dbo.Companies AS t1
INNER JOIN (
SELECT Company, HighestCompany = MAX(CompanyID)
FROM dbo.Companies GROUP BY Company
) AS t2
ON t1.Company = t2.Company
AND t1.CompanyID = t2.HighestCompany
INNER JOIN dbo.Statuses AS s
ON s.StatusID = t1.StatusID;
-- this is a fast, metadata operation that should result
-- in minimal blocking and disruption to end users:
BEGIN TRANSACTION;
ALTER SCHEMA hold TRANSFER dbo.HighestCompany;
ALTER SCHEMA dbo TRANSFER cache.HighestCompany;
ALTER SCHEME cache TRANSFER hold.HighestCompany;
COMMIT TRANSACTION;
Run Code Online (Sandbox Code Playgroud)
如果您发现公司变化如此频繁,或者确实需要更新数据以至于这是不切实际的,则可以使用@Dems建议的触发器来执行类似的操作。
| 归档时间: |
|
| 查看次数: |
7978 次 |
| 最近记录: |