假设我有一张桌子上有5个可以为空的外键。对于每一行,其中只有一行具有值。
现在,这个表已经增长了很多,并且包含了2.2米记录的某些内容。
在大多数情况下,我只对查询表c.q的'parts'感兴趣。某些可以为空的外键具有值的记录。毫不奇怪,只需获取所需的子集需要很长时间,使用下面的查询:28秒来获取一个特定子集的1.7m记录。
SELECT * FROM表WHERE Col IS NOT NULL
我真的很感兴趣我如何才能加快速度,特别是如果可以在不改变数据模型的情况下实现这一点。
答案 0 :(得分:1)
唯一可以加速的事情
SELECT * FROM Table WHERE Col IS NOT NULL
是Col。
的索引但是,从服务器向数据库客户端传输1.7M记录可能需要一段时间,特别是如果它通过网络传输。您可以做的唯一事情是减少发送的数据量,比如只指定SELECT中需要的字段。
答案 1 :(得分:1)
如果我无法更改基表,我会创建一个VIEW,将五个非规范化列转换为两列:origin和value。所以假设你有这个:
Table notNormal (
primaryKey,
someValue,
foreignNotNormal01,
foreignNotNormal02,
foreignNotNormal03,
foreignNotNormal04,
foreignNotNormal05
)
我会创建这个:
CREATE MATERIALIZED VIEW fixedThis AS
SELECT primaryKey, someValue, 'FKCOL01' AS foreignNotNormalOrigin, foreignNotNormal01 AS foreignNotNormalColValue
WHERE foreignNotNormal01 IS NOT NULL
UNION
...
...
SELECT primaryKey, someValue, 'FKCOL01' AS foreignNotNormalOrigin, foreignNotNormal05 AS foreignNotNormalColValue
WHERE foreignNotNormal05 IS NOT NULL
然后我针对fixedThis的SELECTS只显示外键列中的值的结果,无论它们是什么。
如果你只是想要一个简单的加速,指数是要走的路,但实际上,你需要修复数据模型。
答案 2 :(得分:0)
如果您根据这些表是否为空来对数据进行分区,则可能会加快速度 - 所有Col != NULL
的数据都将位于单个分区中。当然,假设这5列是本表中最重要的部分。
CREATE PARTITION FUNCTION MyCol1 (int)
AS RANGE LEFT FOR VALUES (NULL)
CREATE PARTITION SCHEME MySchemeForCol1
AS PARTITION MyCol1
TO Col1FileGroup
重构表会改善一些事情,我会在花费太多时间分割数据之前去那里。像这样的分区仍然可以将事物保存在同一个表中,但是在磁盘上隔离...但是将表重构为一系列链接表会使可能更加有利于你。
如果你对分区有好运,请让大家知道&发布解决方案。
答案 3 :(得分:0)
您是否尝试将该表与所讨论的外键引用的另一个表联系起来?这将删除外键为空的所有条目 我希望联盟的运行速度非常慢,但你可能会感到惊喜。
另外,你有关于外键的索引吗?