MsSQL   发布时间:2022-05-16  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了sql – 加入100个表大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
假设我有一个主表,它有100个列引用(作为外键)到大约100个表(包含主键).

整个信息包需要加入这100个表.而且,加入这么多表格绝对是一个性能问题.希望,我们可以期望任何用户想要在包含条件(在查询的WHERE部分)中的查询中,从不超过约5-7个表(在100个中)中请求一堆数据.约3-4张桌子(其中100张).不同的查询具有用于产生查询的“SELECT”部分的表的不同组合,并将条件置于“WHERE”中.但是,再次,每个SELECT将需要大约5-7个表,并且每个WHERE将需要约3-4个表(肯定地,用于生成SELECT的表的列表可能与用于将条件置于WHERE中的表的列表重叠).

我可以使用底层代码编写一个VIEW加入所有这些100个表.然后我可以将上述SQL查询写入此VIEW.但是在这种情况下,这是一个很大的问题,我如何指示sql Server(尽管在代码中显式指示连接所有这些100个表)只有11个表应该被连接(11个表足以连接以产生SELECT结果并虑到WHERE条件).

另一种方法可能是创建一个转换以下“假”代码的“特征”

SELECT field1,field2,field3 FROM TheFakeTable WHERE field1=12 and field4=5

进入以下“真实”代码:

SELECT T1.field1,T2.field2,T3.field3 FROM TheRealMainTable 
join T1 on ....
join T2 on ....
join T3 on ....
join T4 on ....
WHERE T1.field1=12 and T4.field4=5

从语法的角度来看,即使允许使用“TheFakeTable-mechanism”与实际表和结构的任何混合组合也不是问题.这里的真正问题是如何在技术上实现这个“功能”.我可以创建一个将“假”代码作为输入并产生“真实”代码的函数.但是这并不方便,因为它需要使用动态sql工具evrywhere这个“TheFakeTable-mechanism”出现的位置.一个幻想地解决方案是扩展我的Management studio中的sql语言的语法,以允许编写这样的假代码,然后在发送到服务器之前自动将该代码转换为真实的代码.

我的问题是:

> SQI服务器是否可以指示shomehow(或天才enouh)仅在上述VIEW中加入11个表而不是100个表;
>如果我决定创建这个“TheFakeTable-mechanism”功能,这个功能的技术实现将是最好的形式?

感谢大家每一个评论!

PS
100个表的结构源于我在这里问过的以下问题:
Normalizing an extremely big table

解决方法

sql Server优化器确实包含删除冗余连接的逻辑,但是有限制,连接必须是 provably redundant.总而言之,连接可以有四个效果:

>它可以添加额外的列(从连接的表)
>它可以添加额外的行(连接的表可能多次匹配源行)
>它可以删除行(连接的表可能没有匹配)
>它可以引入NULL(对于RIGHT或FULL JOIN)

要成功删除冗余连接,查询(或视图)必须虑所有四种可能性.当这样做完成时,效果可以令人惊讶.例如:

USE AdventureWorks2012;
GO
create view dbo.ComplexView
AS
    SELECT
        pc.ProductCategoryID,pc.Name AS CatName,ps.ProductSubcategoryID,ps.Name AS SubCatName,p.productID,p.Name AS ProductName,p.Color,p.ListPrice,p.ReorderPoint,pm.Name AS ModelName,pm.ModifiedDate
    FROM Production.ProductCategory AS pc
    FULL JOIN Production.ProductSubcategory AS ps ON
        ps.ProductCategoryID = pc.ProductCategoryID
    FULL JOIN Production.Product AS p ON
        p.productSubcategoryID = ps.ProductSubcategoryID
    FULL JOIN Production.ProductModel AS pm ON
        pm.ProductModelID = p.productModelID

优化器可以成功简化以下查询:

SELECT
    c.ProductID,c.ProductName
FROM dbo.ComplexView AS c
WHERE
    c.ProductName LIKE N'G%';

至:

Rob Farley在original MVP Deep Dives book上深入研究了这些想法,sqlBits上还有一个recording of him presenTing on the topic.

主要的限制是外部关键关系must be based on a single key有助于简化过程,而针对这种观点的查询的编译时间可能变得相当长,特别是随着联接数量的增加.写一个100表视图可能是一个很大的挑战,它使所有的语义完全正确.我会倾向于找到一个替代解决方案,也许使用dynamic SQl.

也就是说,您的非规范化表格的特殊质量可能意味着视图组合非常简单,只需强制执行FOREIGN KEY非NULL引用列,以及适当的UNIQUE约束,使此解决方案能够按期望运行,而不需要100物理联接操作符在计划中.

使用十个表而不是一百个:

-- Referenced tables
create table dbo.Ref01 (col01 Tinyint PRIMary KEY,item varchar(50) NOT NULL UNIQUE);
create table dbo.Ref02 (col02 Tinyint PRIMary KEY,item varchar(50) NOT NULL UNIQUE);
create table dbo.Ref03 (col03 Tinyint PRIMary KEY,item varchar(50) NOT NULL UNIQUE);
create table dbo.Ref04 (col04 Tinyint PRIMary KEY,item varchar(50) NOT NULL UNIQUE);
create table dbo.Ref05 (col05 Tinyint PRIMary KEY,item varchar(50) NOT NULL UNIQUE);
create table dbo.Ref06 (col06 Tinyint PRIMary KEY,item varchar(50) NOT NULL UNIQUE);
create table dbo.Ref07 (col07 Tinyint PRIMary KEY,item varchar(50) NOT NULL UNIQUE);
create table dbo.Ref08 (col08 Tinyint PRIMary KEY,item varchar(50) NOT NULL UNIQUE);
create table dbo.Ref09 (col09 Tinyint PRIMary KEY,item varchar(50) NOT NULL UNIQUE);
create table dbo.Ref10 (col10 Tinyint PRIMary KEY,item varchar(50) NOT NULL UNIQUE);

父表定义(带页压缩):

create table dbo.normalized
(
    pk      Integer IDENTITY NOT NULL,col01   Tinyint nOT NULL REFERENCES dbo.Ref01,col02   Tinyint nOT NULL REFERENCES dbo.Ref02,col03   Tinyint nOT NULL REFERENCES dbo.Ref03,col04   Tinyint nOT NULL REFERENCES dbo.Ref04,col05   Tinyint nOT NULL REFERENCES dbo.Ref05,col06   Tinyint nOT NULL REFERENCES dbo.Ref06,col07   Tinyint nOT NULL REFERENCES dbo.Ref07,col08   Tinyint nOT NULL REFERENCES dbo.Ref08,col09   Tinyint nOT NULL REFERENCES dbo.Ref09,col10   Tinyint nOT NULL REFERENCES dbo.Ref10,CONSTraiNT PK_normalized
        PRIMary KEY CLUSTERED (pk)
        WITH (DATA_COMPRESSION = PAGE)
);

风景:

create view dbo.Denormalized
WITH scheR_415_11845@ABINDING AS
SELECT
    item01 = r01.item,item02 = r02.item,item03 = r03.item,item04 = r04.item,item05 = r05.item,item06 = r06.item,item07 = r07.item,item08 = r08.item,item09 = r09.item,item10 = r10.item
FROM dbo.normalized AS n
JOIN dbo.Ref01 AS r01 ON r01.col01 = n.col01
JOIN dbo.Ref02 AS r02 ON r02.col02 = n.col02
JOIN dbo.Ref03 AS r03 ON r03.col03 = n.col03
JOIN dbo.Ref04 AS r04 ON r04.col04 = n.col04
JOIN dbo.Ref05 AS r05 ON r05.col05 = n.col05
JOIN dbo.Ref06 AS r06 ON r06.col06 = n.col06
JOIN dbo.Ref07 AS r07 ON r07.col07 = n.col07
JOIN dbo.Ref08 AS r08 ON r08.col08 = n.col08
JOIN dbo.Ref09 AS r09 ON r09.col09 = n.col09
JOIN dbo.Ref10 AS r10 ON r10.col10 = n.col10;

破解统计数据使优化器认为表格非常大:

updatE STATISTICS dbo.normalized WITH ROWCOUNT = 100000000,PageCount = 5000000;

用户查询示例

SELECT
    d.item06,d.item07
FROM dbo.Denormalized AS d
WHERE
    d.item08 = 'Banana'
    AND d.item01 = 'Green';

给我们这个执行计划:

归一化表的扫描看起来不好,但是在存储引擎的扫描期间都应用了Bloom过滤器位图(因此,不能匹配的行甚至不能与查询处理器进行比较).这可能足以在您的情况下提供可接受的性能,并且肯定比扫描原始表格及其溢出的列更好.

如果您能够在某个阶段升级到sql Server 2012 Enterprise,则可以使用另一个选项:在归一化表上创建一个列存储索引:

CREATE NONCLUSTERED columNSTORE INDEX cs 
ON dbo.normalized (col01,col02,col03,col04,col05,col06,col07,col08,col09,col10);

执行计划是:

这可能看起来更糟糕,但列存储提供了非常的压缩,整个执行计划以批处理模式运行,并为所有贡献列提供过滤器.如果服务器有足够的线程和内存可用,这个替代方案真的可以飞.

最终,我不知道这种正常化是虑表的数量和获得执行计划不佳或需要过多编译时间的机会的正确方法.我可能会首先纠正非规范化表的模式(适当的数据类型等),可能应用数据压缩…通常的事情.

如果数据真的属于星型模式,则可能需要更多的设计工作,而不仅仅是将重复的数据元素分解成单独的表.

大佬总结

以上是大佬教程为你收集整理的sql – 加入100个表全部内容,希望文章能够帮你解决sql – 加入100个表所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: