postgresql not in
- 作者: 我是金莲二老舅
- 来源: 51数据库
- 2020-09-24
首先说明,in的效率就不高,not的效率更底,所以二者结合就效率不高了。
至于为什么,从大了说,in和not都跟索引没有关系,而且就算相关字段有索引二者也都不会走,走的都是全表查询,那么这肯定不会快。
再说语句本身,not in 首先要判断是不是in,然后在判断not,这是两个过程,相当于一个补集,等于判断了两次,那么自然也就会慢一些。
其实凡是涉及到否判断的都有这样的问题。所以个人一般不建议使用否判断的条件,就算需要有,也需要尽量简化查询内容以后使用(举个简单的例子,原来你的not in需要在1千条数据中查找,现在在10条数据中查找,自然是后者快一些),这样才能让查询更加快捷。
postgresql(8.2)的配置文件中有一个参数log_min_duration_statement,意思是只log执行时间大于设定值的语句,如果设为0,表示log所有语句;如果设为-1,表示不log任何语句。
看起来,这个配置选项对性能的调整是很有用的,比如可以设置:
log_min_duration_statement = 1000
则只log执行时间大于1s的语句,重点优化这些sql语句就好了。
然而,奇怪的,这个选项不太容易生效!经过反复试验,原来需要如下配置:
#debug_print_parse = off
#debug_print_rewritten = off
#debug_print_plan = off
#debug_pretty_print = off
log_connections = off
#log_disconnections = off
log_duration = off
log_line_prefix = '%t [%p]: [%l-1] ' # special values:
# %u = user name
# %d = database name
# %r = remote host and port
# %h = remote host
# %p = pid
# %t = timestamp (no milliseconds)
# %m = timestamp with milliseconds
# %i = command tag
# %c = session id
# %l = session line number
# %s = session start timestamp
# %x = transaction id
# %q = stop here in non-session
# processes
# %% = '%'
# e.g. '<%u%%%d> '
log_statement = 'none' # none, mod, ddl, all
#log_statement = 'all' # none, mod, ddl, all
#log_hostname = off
注意看上面的其中两个选项的设置:
log_duration = off
log_statement = 'none'
这两个选项的意思是不log任何sql语句和执行时间,但是恰恰是关闭了这两个,log_min_duration_statement才会生效!可能postgresql内部 对这两个选项做了“互斥”处理吧。
至于为什么,从大了说,in和not都跟索引没有关系,而且就算相关字段有索引二者也都不会走,走的都是全表查询,那么这肯定不会快。
再说语句本身,not in 首先要判断是不是in,然后在判断not,这是两个过程,相当于一个补集,等于判断了两次,那么自然也就会慢一些。
其实凡是涉及到否判断的都有这样的问题。所以个人一般不建议使用否判断的条件,就算需要有,也需要尽量简化查询内容以后使用(举个简单的例子,原来你的not in需要在1千条数据中查找,现在在10条数据中查找,自然是后者快一些),这样才能让查询更加快捷。
postgresql(8.2)的配置文件中有一个参数log_min_duration_statement,意思是只log执行时间大于设定值的语句,如果设为0,表示log所有语句;如果设为-1,表示不log任何语句。
看起来,这个配置选项对性能的调整是很有用的,比如可以设置:
log_min_duration_statement = 1000
则只log执行时间大于1s的语句,重点优化这些sql语句就好了。
然而,奇怪的,这个选项不太容易生效!经过反复试验,原来需要如下配置:
#debug_print_parse = off
#debug_print_rewritten = off
#debug_print_plan = off
#debug_pretty_print = off
log_connections = off
#log_disconnections = off
log_duration = off
log_line_prefix = '%t [%p]: [%l-1] ' # special values:
# %u = user name
# %d = database name
# %r = remote host and port
# %h = remote host
# %p = pid
# %t = timestamp (no milliseconds)
# %m = timestamp with milliseconds
# %i = command tag
# %c = session id
# %l = session line number
# %s = session start timestamp
# %x = transaction id
# %q = stop here in non-session
# processes
# %% = '%'
# e.g. '<%u%%%d> '
log_statement = 'none' # none, mod, ddl, all
#log_statement = 'all' # none, mod, ddl, all
#log_hostname = off
注意看上面的其中两个选项的设置:
log_duration = off
log_statement = 'none'
这两个选项的意思是不log任何sql语句和执行时间,但是恰恰是关闭了这两个,log_min_duration_statement才会生效!可能postgresql内部 对这两个选项做了“互斥”处理吧。