SQL (ISNULL(@parameter) OR @parameter > Column) 模式的查询优化器以及它是否针对@parameter 为空时进行优化
SQL query optimiser for (ISNULL(@parameter) OR @parameter > Column) patterns and whether it optimises for when @parameter is null
如果我有一个表单,用户可以在其中指定一堆过滤器(例如 productid > 5,category = "Applicances",Price > 3),那么制作一个准备好的语句似乎很自然:
SELECT *
FROM Products
WHERE
(@Price IS NULL OR Price > @Price) AND
(@Category IS NULL OR @Category = Category) AND
(@ProductID IS NULL OR Price > @Product);
然后添加@Price、@Category 和@ProductID 作为参数,当用户没有在表单中输入任何内容时,这些参数为空。
但是,查询优化器是否足够聪明,可以在@Category 和@ProductID 为空时仅使用价格索引?这是因为您将拥有条件 (ISNULL(NULL) OR NULL = Category)
,它始终为真。例如。它做的事情是否与 if:
完全相同
SELECT *
FROM Products
WHERE Price > @Price
准备好了吗?
是否取决于使用的 SQL 引擎? (SQL 服务器,MySQL,SQLite,甲骨文,Postgres)
is the Query Optimiser clever enough for when @Category and @ProductID is null, to only use an Index for the Price?
通常,多个列上的 and
和 or
的组合会提示索引使用情况。在某些数据库中,可以为单个 where
子句使用多个索引。
但是,将查询构建为动态 SQL 可能会更好。 SQL 服务器中的类似内容(与您提供的代码最相似):
DECLARE @sql NVARCHAR(MAX) = '
SELECT *
FROM Products
WHERE 1=1';
IF (@Price IS NOT NULL)
BEGIN
SET @SQL = @SQL + ' Price > @Price'
END;
. . .
然后您可以使用sp_executesql
传递参数。
本质上,代码创建了一系列查询——取决于参数——然后每个查询都可以单独优化。
如果我有一个表单,用户可以在其中指定一堆过滤器(例如 productid > 5,category = "Applicances",Price > 3),那么制作一个准备好的语句似乎很自然:
SELECT *
FROM Products
WHERE
(@Price IS NULL OR Price > @Price) AND
(@Category IS NULL OR @Category = Category) AND
(@ProductID IS NULL OR Price > @Product);
然后添加@Price、@Category 和@ProductID 作为参数,当用户没有在表单中输入任何内容时,这些参数为空。
但是,查询优化器是否足够聪明,可以在@Category 和@ProductID 为空时仅使用价格索引?这是因为您将拥有条件 (ISNULL(NULL) OR NULL = Category)
,它始终为真。例如。它做的事情是否与 if:
SELECT *
FROM Products
WHERE Price > @Price
准备好了吗?
是否取决于使用的 SQL 引擎? (SQL 服务器,MySQL,SQLite,甲骨文,Postgres)
is the Query Optimiser clever enough for when @Category and @ProductID is null, to only use an Index for the Price?
通常,多个列上的 and
和 or
的组合会提示索引使用情况。在某些数据库中,可以为单个 where
子句使用多个索引。
但是,将查询构建为动态 SQL 可能会更好。 SQL 服务器中的类似内容(与您提供的代码最相似):
DECLARE @sql NVARCHAR(MAX) = '
SELECT *
FROM Products
WHERE 1=1';
IF (@Price IS NOT NULL)
BEGIN
SET @SQL = @SQL + ' Price > @Price'
END;
. . .
然后您可以使用sp_executesql
传递参数。
本质上,代码创建了一系列查询——取决于参数——然后每个查询都可以单独优化。