即使在创建索引时,postgres的性能也会降低

Ali*_*ett 3 sql postgresql

我使用md5在postgres中为下面提到的表创建了索引.索引和表格如下:

 create table my_table(col1 character varying, col2 character varying, col3 character varying);
Run Code Online (Sandbox Code Playgroud)

my_table看起来像(我刚刚给出了一个例子.我的实际表是1Tera Byte):

   col1  col2   col3
   <a12> <j178> <k109>

create index index1 on my_table (md5(col1), md5(col2), md5(col2));
Run Code Online (Sandbox Code Playgroud)

我尝试在不使用md5的情况下创建索引,但是我最终得到了错误:

ERROR:  index row size 2760 exceeds maximum 2712 for index "index1"
HINT:  Values larger than 1/3 of a buffer page cannot be indexed.
Consider a function index of an MD5 hash of the value, or use full text indexing.
Run Code Online (Sandbox Code Playgroud)

但是,我注意到无论是否创建索引,我的查询处理时间都保持不变.我很困惑,原因可能是什么.有人可以帮我这个吗?

我解雇的sql查询格式如下:

select col3 from my_table where col1='<a12>' and col2='<j178>';
Run Code Online (Sandbox Code Playgroud)

小智 6

由于在尝试创建标准btree索引时遇到错误,我猜测这些列中的一个或多个列中的数据非常大.

您创建的索引最好描述为"三列的md5哈希值的b树索引",而不是"三列的md5索引".

为了让PostgreSQL使用索引,您的查询必须是md5哈希.尝试:

SELECT col3
FROM my_table 
WHERE
      md5(col1) = md5('<a12>')
  and md5(col2) = md5('<j178>')
Run Code Online (Sandbox Code Playgroud)

计划者会说"哦,我的指数是md5(col1)等,我会用它".请注意,这仅适用于完全相等查询(=),不适用于LIKE或范围查询.它也不会col3从索引中获取值,因为只有md5 col3存储在那里,所以它仍然需要转到表来获取col3值.

对于一个小表,这可能会导致计划者决定跳过索引并只对表进行全面扫描,但听起来你的表足够大以至于索引值得 - postgres将扫描索引,找到匹配的行条目,然后从表中检索这些行.

现在,如果col3其中包含大量数据并且第1列和第2列很小,则可以创建col1,col2.的正常索引.您实际上只需要索引where子句中的列,而不是索引部分中的列select.

postgres索引文档非常好:http://www.postgresql.org/docs/9.0/static/indexes.html但CREATE INDEX页面可能是最有用的一个:http://www.postgresql.org/文档/ 9.1 /静态/ SQL-createindex.html

找出你的索引是否被使用的最好方法是使用"EXPLAIN"指令:http://www.postgresql.org/docs/9.1/static/sql-explain.html - 如果你使用pgadmin3来玩您的数据库(我强烈推荐它)然后只需在查询窗口中按F7,它就会执行解释并将其显示在一个很好的GUI中,向您显示查询计划.这节省了许多小时的毛发,试图找出为什么我的指数没有被使用.