【发布时间】:2019-11-23 16:04:08
【问题描述】:
我在 postgresql 数据库中关注了 2 个表 -
表1
- col1_id(整数)
- col2(文本)
- col3(文本)
- col4(文本)
- col5(数字(1,0))
- col6(数字(9,0))
- col7_created_date(时间戳),
- col8(文本)
CREATE UNIQUE INDEX col1_pkey ON table1 USING btree (col1_id),
表2
- col1_id(整数)
- tab2_col2(文本)
- tab3_col3(文本)
- tab4_col4(整数)
- tab5_col5(文本)
CREATE UNIQUE INDEX table2_pkey ON table2 USING btree (col1_id, tab3_col3)
FOREIGN KEY (col1_id) REFERENCES table1(col1_id) ON UPDATE RESTRICT ON DELETE RESTRICT
注意:从上面的表定义中,你会明白table1中的col1_id不仅是table2中的外键,还是table2中tab3_col3的一部分,支持1:Many关系。
这里的问题是 table1 有 10,00,000 行,而 table2 有 50,00,000 条记录。所以我的查询需要最少 5 秒的时间执行,这是我的查询 -
查询1:
SELECT *
FROM table1 t1
WHERE (col6 >= ?)
AND col5 IN (?)
AND (t1.col8 LIKE ? OR t1.col8 LIKE ?)
ORDER BY col7_created_date DESC
LIMIT 50
查询2:
SELECT COUNT(*)
FROM table1 t1
LEFT JOIN table2 t2 ON t2.col1_id = t1.col1_id
WHERE t1.col7_created_date > ?
AND t2.tab4_col4 = ?
AND t2.tab3_col3 IN (?, ?)
AND a.tab2_col2 IN (?)
理解要点:
- table2 应该有单独的 id 列作为主键以获得良好的性能,因为复合键会降低表中大量数据的性能。我可以解决这个问题。
- 我还可以从 table1 和 table2 中删除一些旧记录,但目前这不是我的选择。
- 在 Query1 中,我无法删除“col7_created_date DESC”,因为我只想要前 50 条记录,分页由业务逻辑控制。
- Query1 中的“LIKE”搜索是动态创建的,可以是 1 或 2..
问题:
- 如果我在 t1.col8 (Query1) 上创建索引会提高性能吗?如果是这样,是否有一种有效的方法来创建索引? (注意:
t1.col8是逗号分隔的文本,最多 4 个) - 我应该做些什么来提高 Query1 和 Query2 的性能,我愿意更改 DDL。有什么建议吗?
【问题讨论】:
-
请重新格式化您的问题。
-
将逗号分隔的值存储在单个列中是一个真的开始的坏主意。在 Postgres 中,您至少应该使用正确的数组
标签: sql postgresql