sql - 如何优化这些 SQL 连接?
问题描述
TL;博士
这是我要优化的连接查询。
SELECT D.Data1, D.Data2
FROM @DATA D
INNER JOIN @FILTER F
ON (
(COALESCE(F.Filter1, D.Data1) = D.Data1)
OR
(
F.Filter1 < 0
AND F.Filter1 <> -D.Data1
)
)
AND
(
(COALESCE(F.Filter2, D.Data2) = D.Data2)
OR
(
F.Filter2 < 0
AND F.Filter2 <> -D.Data2
)
);
背景
这是场景:
我有以下表格:
DECLARE @DATA TABLE (
Data1 INT NOT NULL,
Data2 INT NOT NULL,
-- ...
DataN INT NOT NULL
);
DECLARE @FILTER TABLE (
Filter1 INT NULL,
Filter2 INT NULL,
-- ...
FilterN INT NULL
)
需要根据以下规则按@DATA
列过滤的行:@FILTER
令 1 < X < N。
假设
FilterX IS NULL OR FilterX > 0
所有 X 都为真。假设
DataX > 0
所有 X 都为真。
如果
FilterX is NULL
为真,则DataX
通过过滤器。如果
FilterX > 0 AND FilterX = DataX
为真,则DataX
通过过滤器。如果
FilterX < 0 AND FilterX != -DataX
为真,则DataX
通过过滤器。
DataX
否则过滤器失败。如果
DataX
全部通过过滤器,X
则返回该DATA
行。
这是一个两列方案:
COLUMNS: Column1 Column2
DATA: 24 12
23 12
23 13
FILTER: 24 NULL
NULL -12
EXPECTED: 24 12
23 13
上面的例子可以解释为
DATA
返回where的所有行Data1 = 24 OR Data2 <> -12
我上面的查询完成了结果,但在商业案例中,我有大约 16 个字段而不是两个,这导致了一个丑陋可怕的查询。我想知道是否有一种更高效的方式可以进行这些连接以实现相同的结果。
解决方案
您似乎遇到的主要问题是在WHERE
子句中进行计算。你可以通过做这样的事情来避免其中的一些,我认为这符合你的逻辑。
FROM @DATA D
INNER JOIN @FILTER F
ON
(
(F.Filter1 = D.Data1 OR F.Filter1 IS NULL)
OR
(
F.Filter1 < 0
AND F.Filter1 <> -D.Data1
)
)
AND
(
(F.Filter2 = D.Data2 OR F.Filter2 IS NULL)
OR
(
F.Filter2 < 0
AND F.Filter2 <> -D.Data2
)
);
在此之后我要查看的主要内容是您的表上是否有正确的索引,但我们无权访问您的实际架构来检查哪些索引已到位。
推荐阅读
- regex - 让浏览器忽略 URL 中间的特定字符串的方法?
- python - ImportError:无法从“setuptools”导入名称“Feature”
- android-9.0-pie - (Termux:API)中的“termux-battery-status”命令不起作用
- javascript - 共享 React 组件的开放式样式
- python - 使用 KNearestNeighbors 绘制 Iris 数据集的决策边界的问题
- firebase - 无法在firebase数据库中读取和写入数据
- android-studio - 如何更改复选框背景圆圈的颜色?
- angular - 如何制作调用不同服务的通用方法
- angular - 没有从 nativescript-mediafilepicker 检索到 rawData
- google-cloud-platform - 如何在 GSuite 组级别启用操作系统登录