相关疑难解决方法(0)

PostgreSQL 中的覆盖索引是否有助于 JOIN 列?

我有很多看起来像这样的表格:

CREATE TABLE table1(id INTEGER PRIMARY KEY, t1c1 INTEGER, t1c2 INTEGER);
CREATE TABLE table2(id INTEGER PRIMARY KEY, t1 INTEGER REFERENCES table1(id), t2c1 INTEGER);
Run Code Online (Sandbox Code Playgroud)

我做了很多连接,我试图过滤连接表以从第一个表中获取内容,如下所示:

SELECT t1c1
FROM table1
JOIN table2 ON table2.t1 = table1.id
WHERE t2c1 = 42;
Run Code Online (Sandbox Code Playgroud)

当我为表编写索引时,我会查看 WHERE 子句中使用的列并构建索引以满足它们。所以对于这个查询,我最终会写一个这样的索引:

CREATE INDEX ON table2 (t2c1);
Run Code Online (Sandbox Code Playgroud)

并且这个索引至少有资格在该查询中使用。

我的问题是,如果我写这样的索引:

CREATE INDEX ON table2 (t2c1, t1);
Run Code Online (Sandbox Code Playgroud)

索引会不会作为覆盖索引来帮助上面查询中的JOIN?我应该改变我的索引编写策略来覆盖外键列吗?

postgresql index optimization

13
推荐指数
1
解决办法
2万
查看次数

如何取消嵌套和 GROUP BY JSON 数组的元素?

给定band表格,其中一json列包含一个数组:

id | people
---+-------------
1  | ['John', 'Thomas']
2  | ['John', 'James']
3  | ['James', 'George']
Run Code Online (Sandbox Code Playgroud)

如何列出每个名称所属的乐队数量?
期望的输出:

name   | count
-------+------------
John   | 2
James  | 2
Thomas | 1
George | 1
Run Code Online (Sandbox Code Playgroud)

postgresql group-by array json

9
推荐指数
2
解决办法
2万
查看次数

何时需要 FROM 子句中的 COLUMN 别名?

FROM提供column_alias,SQL 规范调用这些<derived column list>子句。这就是 postgres 文档对它们的描述,

FROM包含别名的项目的替代名称。别名用于简洁或消除自联接(多次扫描同一个表)的歧义。当提供别名时,它完全隐藏了表或函数的实际名称;例如 given FROM foo AS f, 的其余部分SELECT必须将此FROM项目称为fnot foo。如果编写了别名,还可以编写列别名列表来为表的一列或多列提供替代名称。

什么时候需要这些?我什么时候不能只使用 COLUMN 别名?

SELECT t.*
FROM table_name AS t (a,b,c);
Run Code Online (Sandbox Code Playgroud)

对比

SELECT t.col1 AS a, t.col2 AS b, t.col3 AS c
FROM table_name AS t;
Run Code Online (Sandbox Code Playgroud)

这个例子取自@ypercube 选择的答案??这似乎不太有用。

上述上下文中的 FROM 别名不会提供真正的好处,除非您是

  • 依赖部分别名(不别名整个表)
  • 这取决于升序列排序
  • 你的表有超过三列(或者你可以在 from 子句中明确地写出来)。

这样做似乎依赖于常规t.*堆叠的危害,并增加了晦涩。那么什么时候FROM别名有用呢?

postgresql alias

6
推荐指数
1
解决办法
1233
查看次数

为什么这种隐式连接的规划方式与显式连接不同?

在这个答案中,我解释了 SQL-89 的隐式语法。
但是我在玩的时候注意到不同的查询计划:

EXPLAIN ANALYZE
  SELECT *
  FROM (values(1)) AS t(x), (values(2)) AS g(y);

                                     QUERY PLAN                                     
------------------------------------------------------------------------------------
 Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)
 Planning time: 0.052 ms
 Execution time: 0.020 ms
(3 rows)
Run Code Online (Sandbox Code Playgroud)

与此相反:

EXPLAIN ANALYZE
  SELECT *
  FROM (values(1)) AS t(x)                      
  CROSS JOIN (values(2)) AS g(y);
                                           QUERY PLAN                                           
------------------------------------------------------------------------------------------------
 Subquery Scan on g  (cost=0.00..0.02 rows=1 width=4) (actual time=0.004..0.005 rows=1 loops=1)
   ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)
 Planning time: 0.075 ms
 Execution time: 0.027 …
Run Code Online (Sandbox Code Playgroud)

postgresql performance join execution-plan postgresql-9.5 postgresql-performance

5
推荐指数
1
解决办法
1270
查看次数

如何在 ANSI SQL 89 语法中执行 JOIN?

在 Oracle 中,我使用

SELECT * FROM table1...JOIN...
Run Code Online (Sandbox Code Playgroud)

其中点表示连接类型或连接条件。

这是 ANSI 89 语法吗?如果没有,那么如果我使用 ANSI 89,我将如何执行连接?

join sql-standard

3
推荐指数
1
解决办法
2708
查看次数

隐式连接与 Postgres 中的显式连接一样有效吗?

通常这样写很方便:

SELECT * 
FROM t1   # ... +many more tables
INNER JOIN t2 ON (t1.id = t2.col)
INNER JOIN t3 ON (t1.id = t3.col)
INNER JOIN t4 ON (t1.id = t4.col)
...
Run Code Online (Sandbox Code Playgroud)

作为带条件的交叉连接:

SELECT * 
FROM t1, t2, t3, t4   # ... +many more tables
WHERE
       t1.id = t2.col
   AND t1.id = t3.col
   AND t1.id = t4.col
   # +include matches on columns of other tables
Run Code Online (Sandbox Code Playgroud)

但是,交叉连接的简单实现将比内部连接具有更高的时间复杂度。Postgres 是否将第二个查询优化为与第一个查询具有相同时间复杂度的查询?

postgresql join execution-plan

2
推荐指数
1
解决办法
2444
查看次数

WITH ... AS 语句未按预期工作

我收到此错误:

WITH...AS 语法错误

当我尝试执行以下查询时出现:

with expensive_service as (
    select s1.*
    from service s1, service s2
    where s1.price > s2.price
)
select * 
from service except expensive_service;
Run Code Online (Sandbox Code Playgroud)

我试图实现WITH ... AS(链接到 PostgreSQL 文档)。

此查询为我提供了所需的输出:

select * 
from service except ( 
    select s1.*
    from service s1, service s2
    where s1.price > s2.price
)
Run Code Online (Sandbox Code Playgroud)

任何指导我错误所在的帮助将不胜感激!

postgresql cte except

2
推荐指数
1
解决办法
632
查看次数