2013-11-14 88 views
1

我搜索了一下我的问题,但找不到解决方案。慢选择查询与DATE

我运行一个PostgreSQL 9.2.4 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.7.2-5) 4.7.2, 64-bit,我的查询很简单。

EXPLAIN (ANALYZE) SELECT CUSTOMER, PRICE, BUYDATE FROM dbo.Invoice WHERE CUSTOMER = 11111111 AND BUYDATE BETWEEN '2012-11-01' AND '2013-10-31'; 

输出:

                 QUERY PLAN 
----------------------------------------------------------------------------------------------------------------------------------- 
Bitmap Heap Scan on Invoice (cost=88193.54..152981.03 rows=20699 width=14) (actual time=987.205..987.242 rows=36 loops=1) 
    Recheck Cond: ((CUSTOMER = 11111111) AND (BUYDATE >= '2012-11-01'::date) AND (BUYDATE <= '2013-10-31'::date)) 
    -> BitmapAnd (cost=88193.54..88193.54 rows=20699 width=0) (actual time=987.189..987.189 rows=0 loops=1) 
     -> Bitmap Index Scan on ix_Invoice (cost=0.00..1375.69 rows=74375 width=0) (actual time=0.043..0.043 rows=40 loops=1) 
       Index Cond: (CUSTOMER = 11111111) 
     -> Bitmap Index Scan on ix_Invoice3 (cost=0.00..86807.24 rows=4139736 width=0) (actual time=986.562..986.562 rows=4153999 loops=1) 
       Index Cond: ((BUYDATE >= '2012-11-01'::date) AND (BUYDATE <= '2013-10-31'::date)) 
Total runtime: 987.294 ms 
(8 rows) 

表结构:

 Column  |   Type   | Modifiers | Storage | Stats target | Description 
-----------------+---------------------------+-----------+----------+--------------+------------- 
profitcenter | character varying(5)  | not null | extended |    | 
invoicenumber | character varying(10)  | not null | extended |    | 
invoiceposition | character varying(6)  | not null | extended |    | 
buydate   | date      | not null | plain |    | 
customer  | integer     |   | plain |    | 
nettowert  | numeric(18,2)    |   | main  |    | 
Indexes: 
    "filialbons_key" PRIMARY KEY, btree (profitcenter, invoicenumber, invoiceposition, buydate) 
    "ix_Invoice" btree (customer) 
    "ix_Invoice2" btree (invoicenumber) 
    "ix_Invoice3" btree (buydate) 
    "ix_Invoice4" btree (articlenumber) 
Has OIDs: no 

示例输出从查询:

customer | price | buydate 
--------------+-----------+---- 
11111111 | 8.32 | 2013-02-06 
11111111 | 5.82 | 2013-02-06 
11111111 | 16.64 | 2013-02-06 

我跑一个MSSQL 2010相同的查询?将日期列作为varchar()表示,速度更快。

感谢您的帮助

+0

我没有postgre专家,但似乎使用'invoice_ix3'不是最优的 - 不知道表中有多少行我猜,更好的计划是先按ID筛选,然后应用按行逐行过滤日期(而不是“位图和”)。尝试用'select * from(select * from dbo.Invoice WHERE CUSTOMER = 11111111)强制它'BUYDATE BETWEEN'2012-11-01'和'2013-10-31'' – haki

+0

我试过了。这是相同的输出(EXPLAIN ANALYZE),如上所示:( – Beig

+0

你可以让他忽略索引?提示什么的? – haki

回答

2
  1. 与(客户,buydate)查询索引应该更快工作。
  2. 您可以尝试帮助策划师通过收集更多的统计数据,以更好的选择方案:

    ALTER TABLE发票ALTER COLUMN客户SET STATISTICS 1000;
    ALTER TABLE发票ALTER COLUMN buydate SET STATISTICS 1000;
    ANALYZE发票;

+0

谢谢,我认为ANALYZE表做的工作。http://pastebin.com/LX3Mm9aX输出EXPLAIN ANALYSE SELECT。 – Beig

+1

'statistics'后面应该没有相同的数字 – brauliobo

+0

@brauliobo谢谢!修正了答案。 – alexius