【问题标题】:Postgresql very slow query on indexed columnPostgresql对索引列的查询非常慢
【发布时间】:2015-02-06 07:57:56
【问题描述】:

我有 5000 万行的表格。名为 u_sphinx 的一列非常重要,可用值是 1、2、3。现在所有行都有值 3 但是,当我检查新行(u_sphinx = 1)时,查询非常慢。有什么问题?也许索引坏了?服务器:Debian,8GB 4x Intel(R) Xeon(R) CPU E3-1220 V2 @ 3.10GHz

表结构:

base=> \d u_user
表“public.u_user”
         专栏 |类型 |修饰符
 u_ip |性格变化|
 u_agent |正文 |
 u_agent_js |正文 |
 u_resolution_id |整数 |
 u_os |性格变化|
 u_os_id |小号 |
 u_平台 |性格变化|
 u_language |性格变化|
 u_language_id |小号 |
 u_language_js |性格变化|
 u_cookie |小号 |
 u_java |小号 |
 u_color_depth |整数 |
 u_flash |性格变化|
 u_charset |性格变化|
 u_doctype |性格变化|
 u_compat_mode |性格变化|
 u_sex |性格变化|
 u_age |性格变化|
 u_theme |性格变化|
 你的行为 |性格变化|
 u_targeting |性格变化|
 u_resolution |性格变化|
 u_user_hash |大整数 |
 u_tech_hash |性格变化|
 u_last_target_data_time |整数 |
 u_last_target_prof_time |整数 |
 u_id |大整数 |不为空默认 nextval('u_user_u_id_seq'::regclass)
 u_sphinx |小号 |不为空默认 1::smallint
索引:
    “u_user_u_id_pk”主键,btree (u_id)
    “u_user_hash_index” btree (u_user_hash)
    "u_user_u_sphinx_ind" btree (u_sphinx)

慢查询:

base=> 解释分析 SELECT u_id FROM u_user WHERE u_sphinx = 1 LIMIT 1; 查询计划 -------------------------------------------------- -------------------------------------------------- ------------------------- 限制(成本=0.00..0.15 行=1 宽度=8)(实际时间=485146.252..485146.252 行=0 循环=1) -> Seq Scan on u_user (cost=0.00..3023707.80 rows=19848860 width=8) (实际时间=485146.249..485146.249 rows=0 loops=1) 过滤器:(u_sphinx = 1) 过滤器删除的行:23170476 总运行时间:485160.241 毫秒 (5 行)

已解决:

添加部分索引后

base=> 解释分析 SELECT u_id FROM u_user WHERE u_sphinx = 1 LIMIT 1; 查询计划 -------------------------------------------------- -------------------------------------------------- ---------------------------------- 限制(成本=0.27..4.28 行=1 宽度=8)(实际时间=0.063..0.063 行=0 循环=1) -> 在 u_user 上使用 u_user_u_sphinx_index_1 进行索引扫描(成本=0.27..4.28 行=1 宽度=8)(实际时间=0.061..0.061 行=0 循环=1) 指数条件:(u_sphinx = 1) 总运行时间:0.106 毫秒

感谢@Kouber Saparev

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    您的查询计划看起来数据库正在处理查询,就好像 1 在数据库中很常见,因此最好挖掘一两个磁盘页面以识别相关行,而不是增加开销遍历索引并在随机磁盘页面中找到一行。

    这可能表明您忘记运行以分析表,以便规划器具有正确的统计信息:

    analyze u_user
    

    【讨论】:

      【解决方案2】:

      尝试制作部分索引。

      CREATE INDEX u_user_u_sphinx_idx ON u_user (u_sphinx) WHERE u_sphinx = 1;
      

      【讨论】:

      • 删除实际索引并为每个值再创建 3 个?还是不删除第一个索引?
      • 这取决于您对该数据有哪些其他查询,但通常如果您写的几乎“所有行的值都为 3”,那么您不需要完全是旧索引。无论如何,它不会用于值 3。
      • 如果您只添加该索引并运行 EXPLAIN ANALYZE 会发生什么?
      猜你喜欢
      • 2020-05-10
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      • 2014-10-16
      • 2013-12-04
      • 1970-01-01
      • 2013-06-13
      相关资源
      最近更新 更多