我一直在努力寻找从多个表中选择的查询。我原来的查询速度非常慢(53秒)。从阅读起,我现在有理由相信我需要创建一个内部查询来限制迭代的数据。但是当我使用2个以上的表时,我不确定如何使用子查询的结果(内部查询)。下面是一些虚拟表:
+-------+---------------------+------------+
| tr_id | tr_datecreated | tr_depart |
+-------+---------------------+------------+
| 1 | 2011-07-31 00:00:00 | 2011-08-20 |
| 2 | 2011-08-01 00:00:00 | 2011-08-30 |
| 3 | 2011-08-02 00:00:00 | 2011-09-01 |
+-------+---------------------+------------+
+------+--------+---------+---------+
| p_id | p_trid | p_name | p_lname |
+------+--------+---------+---------+
| 1 | 1 | Geoff | Thingy |
| 2 | 1 | Mildred | Thingy |
| 3 | 1 | Garry | Thingy |
| 4 | 2 | Linda | Doobrey |
| 5 | 2 | Kev | Doobrey |
| 6 | 3 | John | Wotsit |
| 7 | 3 | Jill | Wotsit |
+------+--------+---------+---------+
+------+--------+----------+
| h_id | h_trid | h_dest |
+------+--------+----------+
| 1 | 1 | France |
| 2 | 1 | Spain |
| 3 | 2 | Italy |
| 4 | 3 | Portugal |
+------+--------+----------+
我想得到一个结果,如:
+-------+---------------------+------------+---------+---------+----------+
| tr_id | tr_datecreated | tr_depart | p_name | p_lname | h_dest |
+-------+---------------------+------------+---------+---------+----------+
| 1 | 2011-07-31 00:00:00 | 2011-08-20 | Geoff | Thingy | France |
| 1 | 2011-07-31 00:00:00 | 2011-08-20 | Geoff | Thingy | Spain |
| 1 | 2011-07-31 00:00:00 | 2011-08-20 | Mildred | Thingy | France |
| 1 | 2011-07-31 00:00:00 | 2011-08-20 | Mildred | Thingy | Spain |
| 1 | 2011-07-31 00:00:00 | 2011-08-20 | Garry | Thingy | France |
| 1 | 2011-07-31 00:00:00 | 2011-08-20 | Garry | Thingy | Spain |
| 2 | 2011-08-01 00:00:00 | 2011-08-30 | Linda | Doobrey | Italy |
| 2 | 2011-08-01 00:00:00 | 2011-08-30 | Kev | Doobrey | Italy |
| 3 | 2011-08-02 00:00:00 | 2011-09-01 | John | Wotsit | Portugal |
| 3 | 2011-08-02 00:00:00 | 2011-09-01 | Jill | Wotsit | Portugal |
+-------+---------------------+------------+---------+---------+----------+
我们为每个度假目的地的每个人获得一个单独的行。
我最初的努力是:
SELECT tr_id, tr_datecreated, tr_depart, p_name, p_lname, h_dest
FROM transaction, people, holiday
WHERE tr_id = p_trid
AND tr_id = h_trid
AND tr_datecreated >= "2010-12-12 00:00:00"
AND tr_datecreated <= "2012-12-12 00:00:00"
我认为这会产生大量的交叉连接,并且查询运行速度非常慢。
看到tr_id被多次引用我想做一个内部查询,这减少了与其他所有内容进行比较的行数。
所以内部查询部分将是:
SELECT tr_id WHERE tr_datecreated >= "2010-12-12 00:00:00"
AND tr_datecreated <= "2012-12-12 00:00:00"
我如何创建我想要的表格,我希望将p_trid和h_trid与同一内部查询进行比较而不运行该内部查询两次(如果可能)?
在这种情况下,内部联接会有帮助吗? (我已经阅读但尚未完全吸收它。)
感谢这里的任何建议和意见。数据库很大,我需要高效。
修改
索引:
tr_id,h_id和p_id都是主键
EXPLAIN的结果
+----+-------------+--------------+--------+---------------+---------+---------+---------------------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+--------+---------------+---------+---------+---------------------+------+--------------------------------+
| 1 | SIMPLE | holiday | ALL | NULL | NULL | NULL | NULL | 4 | |
| 1 | SIMPLE | people | ALL | NULL | NULL | NULL | NULL | 7 | Using where; Using join buffer |
| 1 | SIMPLE | transactions | eq_ref | PRIMARY | PRIMARY | 4 | db.people.p_trid | 1 | Using where |
+----+-------------+--------------+--------+---------------+---------+---------+---------------------+------+--------------------------------+
答案 0 :(得分:1)
你试过加入吗?
SELECT tr.tr_id, tr.tr_datecreated, tr.tr_depart, p.p_name, p.p_lname, h.h_dest
FROM transaction tr
join people p on tr.tr_id = p.p_trid
join holiday h on tr.tr_id = h.h_trid
WHERE tr_datecreated >= "2010-12-12 00:00:00"
AND tr_datecreated <= "2012-12-12 00:00
还没有测试过这个,但这是一般的想法。
答案 1 :(得分:1)
我认为这应该有效。如果有效,请告诉我。
总查询
SELECT t.id, t.date, t.depart, p.p_name, p.p_lname, h.h_dest
FROM
(SELECT tr_id 'id', tr_datecreated 'date', tr_depart 'depart' FROM transaction
WHERE DATE(tr_datecreated) BETWEEN DATE("2010-12-12 00:00:00")
AND DATE("2012-12-12 00:00:00")) t
JOIN people p ON t.id = p.p_trid
JOIN holiday h ON t.id = h.h_trid;
内部查询
(SELECT tr_id 'id', tr_datecreated 'date', tr_depart 'depart' FROM transaction
WHERE DATE(tr_datecreated) BETWEEN DATE("2010-12-12 00:00:00")
AND DATE("2012-12-12 00:00:00"))
编辑:子查询说明
子查询从上面列出的日期范围中选择事务表中的id,创建日期和离开列。查询末尾右边的“t”允许您对内部查询进行别名,以便您可以使用上面的数据。此外,我在子查询中有'id'
,'date'
和'depart'
的位置也是别名。它允许您使用这些值而无需键入完整的列名称。
希望这会有所帮助。
答案 2 :(得分:1)
我建议在people.p_trid和holiday.h_trid上添加一个索引。 EXPLAIN清楚地表明两个表都没有使用索引。
还要确保transactions.tr_id,people.p_trid和holiday.h_trid的数据类型相同。