B S*_*ven 5 postgresql activerecord ruby-on-rails ruby-on-rails-3 rails-postgresql
假设你想找到进入数据库(最高ID)的最后一个记录匹配的字符串:Model.where(:name => 'Joe').有超过100,000条记录.有很多比赛(比如数千).
最有效的方法是什么?PostgreSQL需要找到所有记录,还是只能找到最后一个?这是一个特别慢的查询吗?
使用Rails 3.0.7,Ruby 1.9.2和PostgreSQL 8.3.
这里的重要部分是具有匹配的索引.您可以尝试这个小测试设置:
创建x用于测试的模式:
-- DROP SCHEMA x CASCADE; -- to wipe it all for a retest or when done.
CREATE SCHEMA x;
CREATE TABLE x.tbl(id serial, name text);
Run Code Online (Sandbox Code Playgroud)
插入10000个随机行:
INSERT INTO x.tbl(name) SELECT 'x' || generate_series(1,10000);
Run Code Online (Sandbox Code Playgroud)
插入另外10000行重复的名称:
INSERT INTO x.tbl(name) SELECT 'y' || generate_series(1,10000)%20;
Run Code Online (Sandbox Code Playgroud)
随机删除10%,使其更真实:
DELETE FROM x.tbl WHERE random() < 0.1;
ANALYZE x.tbl;
Run Code Online (Sandbox Code Playgroud)
查询可能如下所示:
SELECT *
FROM x.tbl
WHERE name = 'y17'
ORDER BY id DESC
LIMIT 1;
Run Code Online (Sandbox Code Playgroud)
- >总运行时间:5.535毫秒
CREATE INDEX tbl_name_idx on x.tbl(name);
Run Code Online (Sandbox Code Playgroud)
- >总运行时间:1.228 ms
DROP INDEX x.tbl_name_idx;
CREATE INDEX tbl_name_id_idx on x.tbl(name, id);
Run Code Online (Sandbox Code Playgroud)
- >总运行时间:0.053毫秒
DROP INDEX x.tbl_name_id_idx;
CREATE INDEX tbl_name_id_idx on x.tbl(name, id DESC);
Run Code Online (Sandbox Code Playgroud)
- >总运行时间:0.048 ms
DROP INDEX x.tbl_name_id_idx;
CREATE INDEX tbl_name_idx on x.tbl(name);
CLUSTER x.tbl using tbl_name_idx;
Run Code Online (Sandbox Code Playgroud)
- >总运行时间:1.144 ms
DROP INDEX x.tbl_name_id_idx;
CREATE INDEX tbl_name_id_idx on x.tbl(name, id DESC);
CLUSTER x.tbl using tbl_name_id_idx;
Run Code Online (Sandbox Code Playgroud)
- >总运行时间:0.047毫秒
使用拟合索引,查询执行速度提高了100多倍.
最佳执行者是一个多列索引,首先是过滤列,最后是排序列.在这种情况下,索引中的
匹配排序顺序有点帮助.
聚类有助于简单索引,因为仍然需要从表中读取许多列,并且这些列可以在聚类后在相邻块中找到.在这种情况下,它对多列索引没有帮助,因为只需从表中获取一个记录.
阅读手册中有关多列索引的更多信息.
所有这些效果都随着桌子的大小而增长.10000行的两个小列只是一个非常小的测试用例.
您可以将查询放在Rails中,ORM将编写正确的SQL:
Model.where(:name=>"Joe").order('created_at DESC').first
Run Code Online (Sandbox Code Playgroud)
这不应导致检索所有模型记录,甚至也不会检索表扫描.
| 归档时间: |
|
| 查看次数: |
1950 次 |
| 最近记录: |