Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql postgres:未使用索引或如何优化_Postgresql_Query Optimization - Fatal编程技术网

Postgresql postgres:未使用索引或如何优化

Postgresql postgres:未使用索引或如何优化,postgresql,query-optimization,Postgresql,Query Optimization,我有一个布尔字段(“test”)上有索引的表。当它为真时,它使用索引,因此加载速度很快,但当它为假时,它不使用索引。有什么不对劲吗 我在这里对其进行了解释和分析: DB_development=# explain analyze SELECT COUNT(*) FROM "users" WHERE "users"."is_test" = 't'; QUERY

我有一个布尔字段(“test”)上有索引的表。当它为真时,它使用索引,因此加载速度很快,但当它为假时,它不使用索引。有什么不对劲吗

我在这里对其进行了解释和分析:

DB_development=# explain analyze SELECT COUNT(*) FROM "users" WHERE "users"."is_test" = 't';
                                                                      QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=22890.67..22890.68 rows=1 width=0) (actual time=1848.655..1848.656 rows=1 loops=1)
   ->  Index Scan using index_users_on_is_test on users  (cost=0.00..22846.51 rows=17665 width=0) (actual time=34.727..1844.081 rows=21457 loops=1)
         Index Cond: (is_test = true)
         Filter: is_test
 Total runtime: 1848.882 ms
(5 rows)

DB_development=# explain analyze SELECT COUNT(*) FROM "users" WHERE "users"."is_test" = 'f';
                                                      QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=84505.74..84505.75 rows=1 width=0) (actual time=9557.632..9557.632 rows=1 loops=1)
   ->  Seq Scan on users  (cost=0.00..84063.72 rows=176807 width=0) (actual time=71.653..9533.595 rows=219531 loops=1)
         Filter: (NOT is_test)
 Total runtime: 9557.655 ms
(4 rows)
更新

我在这里看到它可以忽略索引。。。我认为这是正确的,因为与测试用户相比,非测试用户实际上是相当多的

DB_development=# SELECT COUNT(*) FROM "users" WHERE "users"."is_test" = 't';
 count
-------
 21457
(1 row)

DB_development=# SELECT COUNT(*) FROM "users" WHERE "users"."is_test" = 'f';
 count
--------
 219531
(1 row)
如果是这样的话。。。那我怎么快速数数呢

更新

以下是创建表和索引的步骤:

  create_table "users", :force => true do |t|
    t.integer  "genre_id"
    t.integer  "country_id"
    t.boolean  "is_test",                                          :default => false
    t.datetime "created_at"
    t.datetime "updated_at"

    ... + 90 more fields (it's my main table)
  end

  add_index "users", ["country_id"], :name => "index_users_on_country_id"
  add_index "users", ["genre_id"], :name => "index_users_on_genre_id"
  add_index "users", ["is_test"], :name => "index_users_on_is_test"

  ... + 17 more indexes

可能不使用索引的原因有很多。桌子太小了。列/值组合的选择性不够。PostgreSQL“认为”用另一种方式扫描会更快


我在中用更多的细节和例子描述了它们。

这似乎很正常。。。根据行计数,真实值产生大约10%的行;如果为false,则剩余的90%为false。在后一种情况下,读取整个表的速度要快于按照索引来回移动。(它没有足够的选择性来发挥作用。)

如果您
设置enable_seqscan=off
(仅用于测试目的,不要在
postgresql.conf
中设置它,也不要在生产中使用它,因为它会使其他查询速度大大降低)并重新测试,您可能会发现
false
案例在强制使用索引时速度较慢

就我个人而言,我会删除索引,而是在
(is\u test)中添加部分索引,其中(NOT is\u test)

我也会考虑在代码< >(不是ISSUTTEST)中使用其他大量使用的索引,如果这是一个常见的模式,因为它将大大加快非测试索引的使用。p> 无论如何,如果

设置enable\u seqscan=off
的速度更快(不太可能),那么您的
随机页面成本可能太高


此外,如果您使用的是PostgreSQL 9.2,您可能会得到一个更好的解决方案;它通常能够使用仅索引扫描来避免扫描表。如果索引相对于表来说足够小,并且vacuum运行得足够积极,那么它甚至可能使用仅索引的扫描来查找错误案例,因为它必须读取更少的数据。由于您的表非常宽(90个字段),这似乎很有可能。因此考虑升级。

< P>假设您的成本参数设置处于默认状态,则表约为84063.72-1768页,或640 MB。(用\d+验证)

如果扫描这么多数据需要9秒钟,则可能是服务器严重过载,或者数据未缓存,必须从磁盘读取


您可以通过打开track\u io\u计时,然后使用“explain(analyze,buffers)select…”重新执行查询来获得更好的信息。

请显示
CREATE TABLE
语句,包括所有定义的索引。添加了SQL信息。这不是您添加的SQL。那是什么语言?哦。对。这是Rails(Ruby)中的schema.db。除息的