****编辑****
14ms可能看起来不是很多,但是正如你在下面的“PostgresSQL Explain”中看到的那样,PostgreSQL正在对80,000行进行Seq扫描。必须有办法避免这种扫描并改为进行一些索引查找。
****编辑结束****
我正在玩无模式的想法,我有以下三个表:
表格中填入了100,000个随机条目。
$('input[type=checkbox]').click(function(){
$(this).closest('tr')
.find('input[type=checkbox]').not(this)
.attr('disabled', this.checked);
// Below is the added code
var tdIndex = $(this).closest('td').index() + 1;
$('table').find("tr td:nth-of-type(" + tdIndex + ")")
.find('input[type=checkbox]').not(this)
.attr('disabled', this.checked);
});
在entities(_primary_key SERIAL PRIMARY KEY, _id CHAR(32) UNIQUE,
data BYTEA)
index_username_profile_names(_id CHARE(32) PRIMARY KEY,
key VARCHAR UNIQUE)
index_username_email(_id CHAR(32) PRIMARY KEY, key VARCHAR)
我的SQL查询是:
index_username_email(key)
虽然“test”不会在任何一个'index'表中退出,但无论我是使用PostgreSQL还是MySQL,这都需要14毫秒,所以它一定是我做错了。
知道如何优化它,或者我做错了什么?
谢谢!
Postgres解释:
SELECT data FROM entities WHERE
_id IN (SELECT _id FROM index_users_email WHERE key = 'test')
OR
_id in (SELECT _id FROM index_users_profile_name WHERE key = 'test')
答案 0 :(得分:1)
14毫秒很好。我不知道为什么你认为查询应该在不到一毫秒的时间内运行。设置查询,验证数据在内存中,识别索引的位置等等,有很多工作要做。我把它放在引号中,因为对于大多数查询来说,这是微不足道的。但它可以很容易地加起来毫秒。
其次,如果你正在做实时,请记住以下几点:
就查询而言,我能想到的一件事是使用=
和exists
:
SELECT e.data
FROM entities e
WHERE _id = (SELECT _id FROM index_users_email WHERE key = 'test') OR
EXISTS (SELECT 1 FROM index_users_profile_name iupn WHERE iupn._id = e.id AND iupn.key = 'test');
但最好的情况是,我猜这些会使查询缩短一两毫秒。
答案 1 :(得分:1)
OR
ed(join-)条件通常不好,请尝试UNION
:
SELECT data FROM entities
WHERE _id IN
( SELECT _id
FROM index_users_email
WHERE key = 'test'
)
UNION
SELECT data FROM entities
WHERE _id in
( SELECT _id
FROM index_users_profile_name
WHERE key = 'test'
)
答案 2 :(得分:0)
SELECT data
FROM entities e
LEFT OUTER JOIN index_users_email iue ON e._id=iue._id and iue.key = 'test'
LEFT OUTER JOIN index_users_profile_name iupn ON e._id=iupn._id and iupn .key = 'test'
WHERE
iue._id IS NOT NULL or iupn._id IS NOT NULL
答案 3 :(得分:0)
看起来一个可能的答案是union
和join
:
explain select data from entities as t join (select _id from index_users_email where key = 'test' union select _id from index_users_profile_name where key = 'test') u on t._id = u._id;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=17.32..33.82 rows=2 width=163)
-> Unique (cost=16.90..16.91 rows=2 width=33)
-> Sort (cost=16.90..16.91 rows=2 width=33)
Sort Key: index_users_email._id
-> Append (cost=0.42..16.89 rows=2 width=33)
-> Index Scan using index_users_email_key_idx1 on index_users_email (cost=0.42..8.44 rows=1 width=33)
Index Cond: ((key)::text = 'test'::text)
-> Index Scan using index_users_profile_name_key_idx1 on index_users_profile_name (cost=0.42..8.44 rows=1 width=33)
Index Cond: ((key)::text = 'test'::text)
-> Index Scan using entities__id_key on entities t (cost=0.42..8.44 rows=1 width=196)
Index Cond: (_id = index_users_email._id)
(11 rows)
Time: 0.714 ms
答案 4 :(得分:0)
这将有更好的性能,因为它利用了这些表中的主键:
select data
from entities
where
exists (
select _id
from index_users_email
where key = 'test' and _id = entities._id
) or exists (
select _id
from index_users_profile_name
where key = 'test' and _id = entities._id
)