PostgreSQL:特定值的内部联接

PostgreSQL:特定值的内部联接,postgresql,select,inner-join,Postgresql,Select,Inner Join,执行以下操作是否更好(主要是性能方面): 或: 那么: DELETE FROM users u USING sessions s WHERE u.id = s.user_id AND u.id = 1 AND s.id = 2 RETURNING TRUE; 或: 表架构: CREATE EXTENSION "uuid-ossp"; CREATE TABLE users ( id bigserial PRIMARY KEY, email varchar(254) NOT

执行以下操作是否更好(主要是性能方面):

或:

  • 那么:

    DELETE FROM users u
    USING sessions s
    WHERE u.id = s.user_id
    AND u.id = 1
    AND s.id = 2
    RETURNING TRUE;
    
    或:

  • 表架构:

    CREATE EXTENSION "uuid-ossp";
    
    CREATE TABLE users (
        id bigserial PRIMARY KEY,
        email varchar(254) NOT NULL,
        created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
    );
    CREATE UNIQUE INDEX on users (lower(email));
    
    CREATE TABLE sessions (
        user_id bigint PRIMARY KEY REFERENCES users ON DELETE CASCADE,
        id uuid NOT NULL DEFAULT uuid_generate_v4(),
        created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
    );
    

    每当您指定一个特定的值而不是一个潜在的值范围时,具有常量值的查询应该会更快(尽管使用索引可能不会太快)

    您可以对两者进行
    解释分析
    ,查看估计值与实际值

    我相信,由于查询的第一部分是查看这两列是否相等,因此需要将它们全部进行比较,然后通过查询的第二部分进行进一步筛选

    如果您事先知道这两个值,我认为它不仅可能执行得更好,而且在代码中显式指定这两个值也会读得更好

    编辑: 注意:对于少量数据,查询计划看起来基本相同:

    嵌套循环(成本=0.30..16.34行=1宽度=532) ->在用户u上使用用户索引扫描(成本=0.14..8.16行=1宽度=524)索引条件:(id=1) ->在会话s上使用会话索引扫描(成本=0.15..8.17行=1宽度=24)索引条件:(用户id=1)

    嵌套循环(成本=0.30..16.34行=1宽度=532) ->在用户u上使用用户索引扫描(成本=0.14..8.16行=1宽度=516)索引条件:(id=1) ->在会话s上使用会话索引扫描(成本=0.15..8.17行=1宽度=16)索引条件:(用户id=1)

    SQL Fiddle:

    但是,您应该对数据集进行尝试,以确认查询计划器在两种情况下对您的数据选择相同的计划

    DELETE FROM users u
    USING sessions s
    WHERE u.id = s.user_id
    AND u.id = 1
    AND s.id = 2
    RETURNING TRUE;
    
    DELETE FROM users u
    USING sessions s
    WHERE u.id = 1
    AND s.user_id = 1
    AND s.id = 2
    RETURNING TRUE;
    
    CREATE EXTENSION "uuid-ossp";
    
    CREATE TABLE users (
        id bigserial PRIMARY KEY,
        email varchar(254) NOT NULL,
        created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
    );
    CREATE UNIQUE INDEX on users (lower(email));
    
    CREATE TABLE sessions (
        user_id bigint PRIMARY KEY REFERENCES users ON DELETE CASCADE,
        id uuid NOT NULL DEFAULT uuid_generate_v4(),
        created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
    );