Cost of SORT is slowing down my query

╄→гoц情女王★ 提交于 2019-12-14 03:19:54

问题


PostgreSQL 7.4 (Yep upgrading)

So in my WHERE condition I have this

AND CASE
    WHEN "substring"(t."FieldID"::text, 0, 3) = '01'::text 
        OR "substring"(t."FieldID"::text, 0, 4) = '123'::text 
        OR "substring"(t."FieldID"::text, 0, 5) = '5555'::text 
        OR "substring"(t."FieldID"::text, 0, 6) = '44444'::text 
        OR "substring"(t."FieldID"::text, 0, 3) = '99'::text 
    THEN 1
    ELSE 0
END = 1

Alternate syntax but no change in Cost

AND CASE
    WHEN "substring"(t."FieldID"::text, 0, 3) = '01'::text THEN 1
    WHEN "substring"(t."FieldID"::text, 0, 4) = '123'::text THEN 1
    WHEN "substring"(t."FieldID"::text, 0, 5) = '5555'::text THEN 1
    WHEN "substring"(t."FieldID"::text, 0, 6) = '44444'::text THEN 1
    WHEN "substring"(t."FieldID"::text, 0, 3) = '99'::text THEN 1    
    ELSE 0
END = 1

Looking for a Cost effective way to limit the results by the start of a string. So if the string starts with 01, 123, 5555, 44444 or 99 add it to the result set.

Any thoughts?

Note: the FieldID is indexed Viewing the Explain data to see the bottle necks in the query, when adding the above code is when the cost of the Sort goes way up and slows the return of the data set/results.

Output from Explain:

Sort (cost=88716.84..88719.89 rows=822 width=64)

there is a ton more as the query is complex but if I remove the part of the code the Sort cost goes way down


回答1:


If you are just filtering by the starting chars, you can use like with no problem and it will just use an index.

AND (t."FieldID"::text LIKE '01%' OR 
     t."FieldID"::text LIKE '123%' OR 
     t."FieldID"::text LIKE '5555%' OR
     t."FieldID"::text LIKE '44444%' OR
     t."FieldID"::text LIKE '99%')



回答2:


you might get some traction by defining expression indexes that match the query; something like

CREATE INDEX t_fieldid_prefix_3 ON t (("substring"("FieldID"::text, 0, 3)))
CREATE INDEX t_fieldid_prefix_4 ON t (("substring"("FieldID"::text, 0, 4)))
CREATE INDEX t_fieldid_prefix_5 ON t (("substring"("FieldID"::text, 0, 5)))
CREATE INDEX t_fieldid_prefix_6 ON t (("substring"("FieldID"::text, 0, 6)))

If you're always looking for the same prefixes, include the whole thing in the index:

CREATE INDEX t_fieldid_prefix ON t((CASE
    WHEN "substring"("FieldID"::text, 0, 3) = '01'::text 
        OR "substring"("FieldID"::text, 0, 4) = '123'::text 
        OR "substring"("FieldID"::text, 0, 5) = '5555'::text 
        OR "substring"("FieldID"::text, 0, 6) = '44444'::text 
        OR "substring"("FieldID"::text, 0, 3) = '99'::text 
    THEN 1
    ELSE 0
END))



回答3:


I have no idea whether this is supported by your ancient version, but you could try to create an index on the sort expression to see if that improves the query:

CREATE INDEX idx_case ON the_table (
  (CASE
      WHEN substring("FieldID", 0, 3) = '01' THEN 1
      WHEN substring("FieldID", 0, 4) = '123' THEN 1
      WHEN substring("FieldID", 0, 5) = '5555' THEN 1
      WHEN substring("FieldID", 0, 6) = '44444' THEN 1
      WHEN substring("FieldID", 0, 3) = '99' THEN 1    
      ELSE 0
  END));

With a current version I'm pretty sure this could be used to improve the ORDER BY step




回答4:


Depending on how often this sort of query is run, and also on how much data there is, you might consider calculating some of this external to the query and adding extra columns to use as indexes only. The same way a data warehouse denormalizes to speed up reporting queries.



来源:https://stackoverflow.com/questions/7408499/cost-of-sort-is-slowing-down-my-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!