我使用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中,向您显示查询计划.这节省了许多小时的毛发,试图找出为什么我的指数没有被使用.
| 归档时间: |
|
| 查看次数: |
2837 次 |
| 最近记录: |