我已经谷歌了,并找到了许多类似问题的答案,但无法找到真正好的答案,这符合我的问题。
我正在思考具有大量数据的大表的查询性能,以及在某些条件下从这些表中进行选择。
我想知道,在查询中使用哪个更好的数值选择(例如, select * from myTable where myNumericColumn ...
)。这里更好的是:为空,不为空或 = value 。我的意思是:
select * from myTable where myNumericColumn is null
select * from myTable where myNumericColumn is not null
select * from myTable where myNumericColumn != 0
select * from myTable where myNumericColumn = 0
我读到SQL Server索引NULL值,因此使用它更有效。但这是真正的回答还是只是某些用户的意见?
我需要了解SQL Server和Oracle(在我的问题的一个领域)。
提前致谢。
修改!对不起,我很抱歉。我的意思是优化数据表的结构,以便在查询时达到最佳查询性能。我应该使用一些值而不是NULL值来达到更好的执行速度,或者我需要使用NULL,或者我只需要以正确的方式索引表。我知道这是基于意见的,但我需要专业人士的答案,他们致力于数据库的结构开发,优化和查询。性能
答案 0 :(得分:1)
我想知道什么是真正的问题,因为你试图比较不同的查询,除非表格相应地准备测试。对于性能,有几个东西可以产生不同的答案,如行数,每个值之间的比例。
通常,您编写查询的方式甚至无关紧要,因为查询优化器会重新排列查询,以便根据表中的数据和索引获得最佳结果。
所以最好的方法是测试并检查QUERY PLAN
但你必须比较类似的东西
创建一个具有相同NULL
而不是NULL
的表格,您可以比较前两个查询。
然后创建一个具有相同数量0
和<>0
的表格,并比较性能。
答案 1 :(得分:1)
我有一个包含约200万个用户帐户的表,我用它来测试数据。我添加了两列,COL1&amp; COL2。
以下是我如何设置它:
ALTER TABLE Profile.UserAccount ADD COL1 INT NULL
ALTER TABLE Profile.UserAccount ADD COL2 INT NOT NULL DEFAULT (0)
UPDATE Profile.UserAccount -- Update ~75k rows
SET COL1 = 1,
COL2 = 1
WHERE PasswordIsExpired = 'Y'
CREATE INDEX DELETE_ME1 ON Profile.UserAccount (COL1)
CREATE INDEX DELETE_ME2 ON Profile.UserAccount (COL2)
然后我将以下查询放入SSMS并运行它们,输出查询计划。这给出了“相对于批次的查询成本”百分比。如果他们都回来了25%,这意味着他们都会有相同的成本(4个查询x 25%= 100%的批次)。
我在每个语句旁边添加了查询开销。成本越低,查询相对于其他查询的效率就越高:
-- Query Cost: 50%
SELECT COUNT(*) FROM Profile.UserAccount WHERE COL1 IS NULL
/*
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 12 ms, elapsed time = 12 ms.
Table 'UserAccount'. Scan count 1, logical reads 2634, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 250 ms, elapsed time = 481 ms.
*/
-- Query Cost: 3%
SELECT COUNT(*) FROM Profile.UserAccount WHERE COL1 IS NOT NULL
/*
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Table 'UserAccount'. Scan count 1, logical reads 136, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 16 ms, elapsed time = 35 ms.
*/
-- Query Cost: 45%
SELECT COUNT(*) FROM Profile.UserAccount WHERE COL2 = 0
/*
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
Table 'UserAccount'. Scan count 1, logical reads 2068, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 250 ms, elapsed time = 441 ms.
*/
-- Query Cost: 2%
SELECT COUNT(*) FROM Profile.UserAccount WHERE COL2 != 0
/*
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
Table 'UserAccount'. Scan count 2, logical reads 113, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 31 ms, elapsed time = 159 ms.
*/