Dmi*_*kin 2 sql postgresql indexing select
面临在选择条件的地方使用列别名的需要.找到可行的解决方案在这里.
假设我们有一对一的关系(用户到角色),我们希望获得如下结果:
SELECT u.name AS u_name, r.name AS r_name
FROM users AS u
INNER JOIN roles AS r
ON u.role_id = r.role_id
WHERE u.name = 'John'
Run Code Online (Sandbox Code Playgroud)
我们有相应的idex user.name(仅举例).
如果运行此查询EXPLAIN,则显示选择期间使用的所有索引(包括名称索引).
现在,因为我们想在WHERE子句中使用别名,基于提出的解决方案,我们可以重写查询:
SELECT * FROM (
SELECT u.name AS u_name, r.name AS r_name
FROM users AS u
INNER JOIN roles AS r
ON u.role_id = r.role_id
) AS temp
WHERE u_name = 'John'
Run Code Online (Sandbox Code Playgroud)
如您所见,WHERE嵌套选择中没有子句.运行此查询EXPLAIN会得到相同的结果(只是承认,我不是分析'解释'结果的专家,但仍然):
我对此结果感到有点困惑:确信至少不会使用用户名索引.
Q1: postgres是否以这种方式使用索引?
Q2:是否存在性能问题?
子查询不是必需的,因此可以展开/折叠.
以下查询将生成一个平面计划(并且索引不相关)
\i tmp.sql
CREATE TABLE t
(a integer not null primary key
);
insert into t(a)
select v from generate_series(1,10000) v
;
ANALYZE t;
EXPLAIN
SELECT * from (
select d AS e from (
select c as d from (
select b AS c from (
select a AS b from t
) s
) r
) q
) p
where e =95
;
Run Code Online (Sandbox Code Playgroud)
结果计划:
DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 10000
ANALYZE
QUERY PLAN
---------------------------------------------------------------------
Index Only Scan using t_pkey on t (cost=0.17..2.38 rows=1 width=4)
Index Cond: (a = 95)
(2 rows)
Run Code Online (Sandbox Code Playgroud)
在OP的片段中,最里面的查询(表表达式)是一个双表连接,但机制是相同的:所有外层都可以剥离(并重命名结果列)
是的:连接将受益于连接字段的索引,最终也可以使用索引.
| 归档时间: |
|
| 查看次数: |
61 次 |
| 最近记录: |