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'
我们有相应的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'
如您所见,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
        ;
结果计划:
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)
在OP的片段中,最里面的查询(表表达式)是一个双表连接,但机制是相同的:所有外层都可以剥离(并重命名结果列)
是的:连接将受益于连接字段的索引,最终也可以使用索引.