我有一个基本的性能问题。我已经完成了很多SQL查询,但在复杂的内连接方面并没有那么多。所以,这是:
我有一个包含4个表,国家,地区,员工和交易的数据库。
交易与员工和国家联系起来。员工与地区联系。为了生成所需的报告,我运行了一个PHP脚本来处理针对mySQL数据库的SQL查询。
SELECT trans.transactionDate, agent.code, agent.type, trans.transactionAmount, agent.territory
FROM transactionTable as trans
INNER JOIN
(
SELECT agent1.code as code, agent1.type as type, territory.territory as territory FROM agentTable as agent1
INNER JOIN territoryTable as territory
ON agent1.zip=territory.zip
) AS agent
ON agent.code=trans.agent
ORDER BY trans.agent
代理表中大约有50,000条记录,事务表中大约有200,000条记录。另外两个相对较小。它需要大约7分钟来运行此查询。而且我还没有插入第四个表,它需要将transactionTable(country)中的字段与countryTable(country)中的字段相关联,并返回countryTable(region)中的字段。
所以,有两个问题:
我会在哪里逻辑地建立transactionTable和countryTable之间的连接?
有人可以建议一种可以加快速度的方法吗?
感谢。
答案 0 :(得分:0)
您的查询应与此相同:
SELECT tx.transactionDate,
a.code,
a.type,
tx.transactionAmount,
t.territory
FROM transactionTable tx,
agentTable a,
territoryTable t
WHERE tx.agent = a.code
AND a.zip = t.zip
ORDER BY tx.agent
或者如果你想使用JOIN
:
SELECT tx.transactionDate,
a.code,
a.type,
tx.transactionAmount,
t.territory
FROM transactionTable tx
JOIN agentTable a ON tx.agent = a.code
JOIN territoryTable t ON a.zip = t.zip
ORDER BY tx.agent
为了快速工作,您必须在表上使用以下索引:
CREATE INDEX transactionTable_agent ON transactionTable(agent);
CREATE INDEX territoryTable_zip ON territoryTable(zip);
CREATE INDEX agentTable_code ON agentTable(code);
(基本上任何属于WHERE
或JOIN
约束的字段都应编入索引。
也就是说,从某种意义上说,你的表格结构看起来很可疑,因为它显然是非独特的字段,比如邮政编码。你真的想加入更多独特的实体,比如代理ID,事务ID等等 - 否则你的查询会产生很多冗余数据而且速度很慢。
还有一点需要注意:INNER JOIN
相当于简单JOIN
,没有理由输入冗余子句。