SQL性能,在SELECT和WHERE条件下什么执行得更快
更新:废话!它不是一个整数,而是字符变化(10) 像这样执行查询使用索引SQL性能,在SELECT和WHERE条件下什么执行得更快,sql,postgresql,query-optimization,query-performance,Sql,Postgresql,Query Optimization,Query Performance,更新:废话!它不是一个整数,而是字符变化(10) 像这样执行查询使用索引 SELECT t."FieldID" FROM table t WHERE t."FieldID" = '0123456789' 但如果我执行此操作,则不使用索引 SELECT t."FieldID" FROM table t WHERE t."FieldID" LIKE '01%' 还是这个 SELECT t."FieldID" FROM table t WHERE "substring"(t."FieldID",
SELECT t."FieldID"
FROM table t
WHERE t."FieldID" = '0123456789'
但如果我执行此操作,则不使用索引
SELECT t."FieldID"
FROM table t
WHERE t."FieldID" LIKE '01%'
还是这个
SELECT t."FieldID"
FROM table t
WHERE "substring"(t."FieldID", 0, 3) = '01'
还有这个
SELECT t."FieldID"
FROM table t
WHERE t."FieldID" ~ '^01'
我的索引如下所示
CREATE UNIQUE INDEX fieldid_index
ON "table"
USING btree
("FieldID");
运行PostgreSQL 7.4(Yep升级)
我正在优化我的查询,并想知道在语句的SELECT或WHERE子句中使用三种类型的表达式中的一种是否会提高性能
注意:使用这些类型的约束执行的查询将返回大约200000条记录
示例数据是一个变化的字符(10):0123456789
,它也被索引
1。(子字符串)
2。(喜欢)
3。(RegEx)
在WHERE子句中使用一个比另一个有性能优势吗
1。(子字符串)
2。(喜欢)
3。(RegEx)
在SELECT中使用一个选项,在WHERE子句中使用另一个选项是否会提高性能 我个人认为,不应该允许制造这种问题的人使用“性能”这个词。IMHO,对数值字段(甚至可能是键字段)内容的文本表示形式的限制(如WHERE子句中的限制)表明设计不好
如果这是我的数据,我会在记录中添加一个flagfield,在查询xyz中指示想要/不想要。人们甚至可以把它放在一张单独的桌子上。我更喜欢添加一个(冗余?)列,而不是基于GW基本子字符串垃圾创建整个索引。最有效的两件事是索引和可搜索性。Sargability意味着使用可以利用索引的表达式。您可以使用
ANALYZE your_first_table;
-- ANALYZE other tables used in this query.
EXPLAIN ANALYZE
SELECT ...
有关详细信息,请参阅文档
你可能会利用或。PostgreSQL 7.4支持表达式索引和部分索引。对于测试,您可以。(同样在7.4中。)
可能适合您的基于表达式的索引:
create index firsttwochars
on your-table-name (substring(your-column-name from 1 for 2));
但是您仍然需要测试查询,以查看它们是否实际使用了索引。(不管他们是不是sargable。)这个可能有用
select your-column-name
from your-table-name
where substring(your-column-name from 1 for 2) = '01'
前两个字符上没有索引的查询计划。(我的测试表使用随机纯文本用户名,这就是为什么我搜索“ab”而不是“01”。)
索引位于前两个字符上的查询计划
Bitmap Heap Scan on substring (cost=4.36..37.61 rows=14 width=11) (actual time=0.036..0.056 rows=14 loops=1)
Recheck Cond: (substring((username)::text, 1, 2) = 'ab'::text)
-> Bitmap Index Scan on firsttwochars (cost=0.00..4.36 rows=14 width=0) (actual time=0.028..0.028 rows=14 loops=1)
Index Cond: (substring((username)::text, 1, 2) = 'ab'::text)
Total runtime: 0.098 ms
在select列表中,这三个表达式之间可能没有太大区别。都是CPU时间 对于
WHERE
子句,可以添加表达式索引,例如
CREATE INDEX foo ON sometable ((
CASE
WHEN "substring"("FieldID"::text, 0, 3) = '01'::text
THEN 1
ELSE 0
END
));
但是这样一个布尔索引的选择性可能会很差,以至于规划者不会感兴趣。最好将WHERE
子句重写为
WHERE "substring"("FieldID"::text, 0, 3) = '01'::text
然后索引
对于<>代码> 和ReGEX事例,您可以考虑<代码> TythOpTypnnopops索引;看
总而言之,我认为您需要对该查询进行一些清理工作。在SQL Server中,带有
的版本(如'01%'
将是可搜索的。它实际上将这些查询转换为类似的查询,而不使用前导通配符来进行范围查询
执行计划将seek谓词显示为YourCol>='01'和YourCol<'02'
也许类似的重写可以在Postgresql中有所帮助?您不能查看执行计划,看看哪个(如果有的话)为您提供了seek而不是scan吗?使用单个查询中的任何选项只能提供scan,如何调用seek?结果集大约为200K0123456789
不是整数,因为整数没有前导零(123456789
是整数值)@Martin Smith:正则表达式“^01”看起来确实像字符串。整数没有前导零。这将使范围查询(Martin Smith,上图)再次成为可能。感谢您的帮助,我还更新了我的问题,以努力澄清一些问题more@PhillPafford:PostgreSQL 7.4支持部分索引和基于表达式的索引,因此,您应该能够立即提高性能。(我以为基于表达式的索引添加到了8.0中;我错了。)谢谢你的帮助,我还更新了我的问题,以便进一步澄清问题。谢谢你的帮助,我还更新了我的问题,以便进一步澄清问题。原来的问题更难看。这个话题不是关于性能的;是关于(缺乏)设计。可以理解,这不是我的设计,我只是想让一个项目按照他们指定的方式运作
ANALYZE your_first_table;
-- ANALYZE other tables used in this query.
EXPLAIN ANALYZE
SELECT ...
create index firsttwochars
on your-table-name (substring(your-column-name from 1 for 2));
select your-column-name
from your-table-name
where substring(your-column-name from 1 for 2) = '01'
Seq Scan on substring (cost=0.00..205.00 rows=50 width=11) (actual time=0.315..4.377 rows=14 loops=1)
Filter: (substring((username)::text, 1, 2) = 'ab'::text)
Total runtime: 4.414 ms
Bitmap Heap Scan on substring (cost=4.36..37.61 rows=14 width=11) (actual time=0.036..0.056 rows=14 loops=1)
Recheck Cond: (substring((username)::text, 1, 2) = 'ab'::text)
-> Bitmap Index Scan on firsttwochars (cost=0.00..4.36 rows=14 width=0) (actual time=0.028..0.028 rows=14 loops=1)
Index Cond: (substring((username)::text, 1, 2) = 'ab'::text)
Total runtime: 0.098 ms
CREATE INDEX foo ON sometable ((
CASE
WHEN "substring"("FieldID"::text, 0, 3) = '01'::text
THEN 1
ELSE 0
END
));
WHERE "substring"("FieldID"::text, 0, 3) = '01'::text