我正在運行此Postgres問題,如果在查詢字符串中使用參數vs硬編碼其值,則相同查詢需要很長時間才能執行。列名是'media_type',它是一個VARCHAR(20)。我從PHP運行這些查詢,使用Symfony2和Doctrine2 ORM,並且有問題的表有大約1.000.000條記錄。當使用參數代替硬編碼字符串時,Postgres查詢速度很慢
我的查詢有問題嗎?它可以是Postgres配置問題嗎?
1 - 爲MEDIA_TYPE硬編碼值
duration: 5.365 ms parse pdo_stmt_00000001: SELECT id,site_id FROM item where media_type = 'Collection' AND enabled = 'true' AND site_id = $1 AND user_id = $2 ORDER BY id DESC LIMIT $3 OFFSET $4
duration: 0.142 ms bind pdo_stmt_00000001: SELECT id,site_id FROM item where media_type = 'Collection' AND enabled = 'true' AND site_id = $1 AND user_id = $2 ORDER BY id DESC LIMIT $3 OFFSET $4
parameters: $1 = '1', $2 = '1', $3 = '100', $4 = '0'
duration: 8.667 ms execute pdo_stmt_00000001: SELECT id,site_id FROM item where media_type = 'Collection' AND enabled = 'true' AND site_id = $1 AND user_id = $2 ORDER BY id DESC LIMIT $3 OFFSET $4
parameters: $1 = '1', $2 = '1', $3 = '100', $4 = '0'
執行計劃:
duration: 8.640 ms plan:
Query Text: SELECT id,site_id FROM item where media_type = 'Collection' AND enabled = 'true' AND site_id = $1 AND user_id = $2 ORDER BY id DESC LIMIT $3 OFFSET $4
Limit (cost=8.38..8.38 rows=1 width=12) (actual time=8.516..8.595 rows=24 loops=1)
Buffers: shared hit=10 read=15
-> Sort (cost=8.38..8.38 rows=1 width=12) (actual time=8.505..8.530 rows=24 loops=1)
Sort Key: id
Sort Method: quicksort Memory: 26kB
Buffers: shared hit=10 read=15
-> Index Scan using item_media_type_index on item (cost=0.00..8.37 rows=1 width=12) (actual time=7.955..8.397 rows=24 loops=1)
Index Cond: ((media_type)::text = 'Collection'::text)
Filter: (enabled AND (site_id = $1) AND (user_id = $2))
Buffers: shared hit=8 read=15
2 - 使用的參數爲媒體類型(更慢)
duration: 5.557 ms parse pdo_stmt_00000001: SELECT id,site_id FROM item where media_type = $1 AND enabled = 'true' AND site_id = $2 AND user_id = $3 ORDER BY id DESC LIMIT $4 OFFSET $5
duration: 1.322 ms bind pdo_stmt_00000001: SELECT id,site_id FROM item where media_type = $1 AND enabled = 'true' AND site_id = $2 AND user_id = $3 ORDER BY id DESC LIMIT $4 OFFSET $5
parameters: $1 = 'Collection', $2 = '1', $3 = '1', $4 = '100', $5 = '0'
duration: 71564.998 ms execute pdo_stmt_00000001: SELECT id,site_id FROM item where media_type = $1 AND enabled = 'true' AND site_id = $2 AND user_id = $3 ORDER BY id DESC LIMIT $4 OFFSET $5
parameters: $1 = 'Collection', $2 = '1', $3 = '1', $4 = '100', $5 = '0'
執行計劃:
duration: 71564.922 ms plan:
Query Text: SELECT id,site_id FROM item where media_type = $1 AND enabled = 'true' AND site_id = $2 AND user_id = $3 ORDER BY id DESC LIMIT $4 OFFSET $5
Limit (cost=90663.16..181326.31 rows=17184 width=12) (actual time=3.667..71564.864 rows=24 loops=1)
Buffers: shared hit=183786 read=96585
-> Index Scan Backward using item_pkey on item (cost=0.00..906610.46 rows=171836 width=12) (actual time=3.655..71564.798 rows=24 loops=1)
Filter: (enabled AND ((media_type)::text = $1) AND (site_id = $2) AND (user_id = $3))
Buffers: shared hit=183786 read=96585
在此先感謝。
謝謝! PostgreSQL 9.2有預期的發佈日期嗎?我沒有幸運地找到它。另外,PostgreSQL測試版通常有多穩定? – luis
感謝您的好消息。 (和往常一樣,感謝Tom Lane)。 –
@luis我儘可能爲我的開發工作運行PostgreSQL測試版,並且從未遇到過問題。但是,我沒有在生產中使用它們。如果你仍然處於開發階段,使用測試版是不容易的。對於生產 - 呃,一般來說Pg是非常穩定的,雖然這裏偶爾會遇到一些危險的錯誤,但由於迴歸測試的緣故,它們通常處於奇怪的角落。我不能建議你在生產環境中運行測試版 - 它的測試版有一個原因,團隊認爲它沒有準備好 - 但如果我必須面對嚴重問題,我會這樣做。如果可能,請解決並等待發布。 –