我希望为数据库创建索引以实现更好的性能。我正在使用这个查询:
SELECT DISTINCT t1.* FROM current_order
AS t1 LEFT JOIN
receipt AS t2 USING (paper_id,subscriber_id)
WHERE t2.id NOT IN (SELECT id
FROM receipt WHERE paid_till_date > Now())
UNION
SELECT current_order.* FROM receipt RIGHT JOIN
current_order USING (paper_id, subscriber_id)
Where receipt.id IS NULL ORDER BY
subscriber_id, paper_id
Run Code Online (Sandbox Code Playgroud)
表是:
PAPER
id
name
SUBSCRIBER
id
name
address
suburb
state
postcode
round_id
CURRENT ORDER
paper_id
subscriber_id
ROUND
id
name
paperboy
RECEIPT
id
receipt_date
paid_till_date
paper_id
subscriber_id
Run Code Online (Sandbox Code Playgroud)
我知道主键已经被索引,我应该使用一个索引,其中 WHERE 子句和 ORDER BY 子句经常使用。所以我假设订阅者名称将是一个很好的索引?还有收货日期?
任何提示表示赞赏
原始查询
SELECT DISTINCT t1.*
FROM current_order AS t1
LEFT JOIN receipt AS t2 USING (paper_id,subscriber_id)
WHERE t2.id NOT IN (
SELECT id
FROM receipt
WHERE paid_till_date > Now()
)
UNION
SELECT current_order.*
FROM receipt
RIGHT JOIN current_order USING (paper_id, subscriber_id)
WHERE receipt.id IS NULL
ORDER BY subscriber_id, paper_id
Run Code Online (Sandbox Code Playgroud)
比必要的更复杂。
基表是
CURRENT ORDER
paper_id
subscriber_id
Run Code Online (Sandbox Code Playgroud)
和
RECEIPT
id
receipt_date
paid_till_date
paper_id
subscriber_id
Run Code Online (Sandbox Code Playgroud)
OP 指出这receipt.id是主键,我认为这(paper_id,subscriber_id)是主键current order。
两个查询
SELECT t1.*
FROM current_order AS t1
LEFT JOIN receipt AS t2 USING (paper_id,subscriber_id)
WHERE t2.id NOT IN (
SELECT id
FROM receipt
WHERE paid_till_date > Now()
)
Run Code Online (Sandbox Code Playgroud)
和
SELECT t1.*
FROM current_order AS t1
LEFT JOIN receipt AS t2 USING (paper_id,subscriber_id)
WHERE paid_till_date <= Now()
or paid_till_date is NULL
Run Code Online (Sandbox Code Playgroud)
是等价的:两个查询的结果集恰好包含以下元组:
all tuples from current_order where there is a RECEIPT with the same (paper_id,subscriber_id) and paid_till_date <= Now()
all tuples from current_order where there is a RECEIPT with the same (paper_id,subscriber_id) and paid_till_date is NULL
all tuples from current_order where there is no RECEIPT with the same (paper_id,subscriber_id) (and therefore paid_till_date is NULL)
Run Code Online (Sandbox Code Playgroud)
因此,查询是等效的。如果将 DISTINCT 添加到 select 子句,它们也是等效的。
查询的结果集
SELECT current_order.*
FROM receipt
RIGHT JOIN current_order USING (paper_id, subscriber_id)
WHERE receipt.id IS NULL
ORDER BY subscriber_id, paper_id
Run Code Online (Sandbox Code Playgroud)
包含以下元组
all tuples from current_order where there is no RECEIPT with the same (paper_id,subscriber_id) (and therefore receipt.id is NULL)
Run Code Online (Sandbox Code Playgroud)
所以原来的查询可以改为更简单的查询
SELECT DISTINCT t1.*
FROM current_order AS t1
LEFT JOIN receipt AS t2 USING (paper_id,subscriber_id)
WHERE paid_till_date <= Now()
or paid_till_date is NULL
Run Code Online (Sandbox Code Playgroud)
也许 (paper_id,subscriber_id,paid_till_date) 上的索引会很有用。该查询仅使用索引中找到的列(不再使用receipt.id)。“当前订单”的 (paper_id,subscriber_id) 上的索引已存在,因为这是主键。
| 归档时间: |
|
| 查看次数: |
424 次 |
| 最近记录: |