2017-08-29 80 views
1

我遇到了计数查询的麻烦,它太慢了。然后我发现一篇文章谈论PostgreSQL上的Count Estimate。它使用了以下功能来估计行的量:PostgreSQL的计数估计

CREATE OR REPLACE FUNCTION public.count_estimate(query text) 
    RETURNS integer AS 
$BODY$ 
DECLARE 
    rec record; 
    ROWS INTEGER; 
BEGIN 
    FOR rec IN EXECUTE 'EXPLAIN ' || query LOOP 
     ROWS := SUBSTRING(rec."QUERY PLAN" FROM ' rows=([[:digit:]]+)'); 
     EXIT WHEN ROWS IS NOT NULL; 
    END LOOP; 

    RETURN ROWS; 
END 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION public.count_estimate(text) 

我用它像这样:

SELECT count_estimate('SELECT * FROM table'); 

我传递给函数查询接受条件(=,>,<,LIKE ,似乎...),但是当我尝试使用这个特定的条件~它会返回一个错误的计数。

有无论如何去适应此功能,使其在where子句中与~一起使用?

谢谢

+0

你是什么意思与“返回一个错误的计数”?你是否知道执行计划返回**估计**?优化器没有足够的信息来正确表示正则表达式匹配的数量。在执行计划中使用正则表达式匹配,你无法靠近现实。 –

+0

我知道它会返回一个估计值,但在这种情况下,它只返回3行,实际数量为800行。就像你在使用正则表达式时所说的,我并没有接近现实。 :( – Andre

+1

对此你没有办法做到,Postgres没有存储足够的统计数据能够给你一个更好的估计。 –

回答

1

https://www.postgresql.org/docs/current/static/sql-explain.html

https://www.postgresql.org/docs/current/static/using-explain.html

使用的功能,只是运行EXPLAIN并解析输出,显示行的预期数量。 “适应”函数以在此显示更好的结果的唯一方法是在EXPLAIN之后添加ANALYZE以获取“实际”行。但是,当然这会花费你实际执行的查询作为参数传递,所以在运行实际查询之前估计计数是没有意义的,如果在实际运行之后进行估计的话。