存在两个表格:
maindata = id, devid, value (10M行)
djournal = id, devid, md_id_begin, md_id_end, state (10k行)
我想select所有从maindata的某些devid除了有错误state行:
SELECT md.* FROM maindata AS md LEFT JOIN djournal AS dj ON md.id BETWEEN dj.md_id_begin AND dj.md_id_end AND md.devid = dj.devid WHERE md.devid = 123456789 AND dj.state <> 'idle' ORDER BY md.id ASC;
给定查询产生正是我想要的,但sloooooow。 所有可能的指数已经创build。 当然,将state字段直接存储在maindata表中很容易,但是为什么查询速度太慢并且存在任何解决方法?
你只是有索引问题。
你没有发布数据库结构,但是如果你问这个问题,这是因为你不太了解数据库(因为每个不错的数据库服务器都可以显示你的查询花在哪里)。
你缺less的索引可能是在md_id_begin , md_id_end以及state 。 只是一个猜测。
索引id也可能是一个非常好的主意,如果你没有。
对不起,人们,没有解决scheme存在这个问题。 这根本不是问题,这是一个正常的sql引擎的行为。 我试图解释为什么。 让我们有两套:
mysql> select * from Q; mysql> select * from R; +----+------+ +----+------+ | id | val | | id | val | +----+------+ +----+------+ | 1 | a | | 1 | a | | 2 | b | | 2 | b | | 3 | c | | 3 | c | | 4 | d | | 4 | d | | 5 | e | | 5 | e | +----+------+ +----+------+
让一个JOIN没有条件:
mysql> SELECT Q.val AS Qval, R.val AS Rval FROM Q JOIN R; +------+------+ | Qval | Rval | +------+------+ | a | a | | b | a | | c | a | | d | a | | e | a | | a | b | | b | b | | c | b | | d | b | | e | b | | a | c | | b | c | | c | c | | d | c | | e | c | | a | d | | b | d | | c | d | | d | d | | e | d | | a | e | | b | e | | c | e | | d | e | | e | e | +------+------+ 25 rows in set (0.00 sec)
让我们通过“=”条件来调整JOIN:
mysql> SELECT Q.val AS Qval, R.val AS Rval FROM Q JOIN R ON Q.val = R.val; +------+------+ | Qval | Rval | +------+------+ | a | a | | b | b | | c | c | | d | d | | e | e | +------+------+ 5 rows in set (0.00 sec)
当我们join“>”时,我们得到:
mysql> SELECT Q.val AS Qval, R.val AS Rval FROM Q JOIN R ON Q.val > R.val; +------+------+ | Qval | Rval | +------+------+ | b | a | | c | a | | d | a | | e | a | | c | b | | d | b | | e | b | | d | c | | e | c | | e | d | +------+------+ 10 rows in set (0.00 sec)
松懈的状态会产生松懈的结果。 复杂条件减less了结果集,但显着增加了计算量。 当我们joinBETWEEN或<或>时,我们得到了大量的临时表,用于中间结果 – 没有索引,由filesortsearch。
所以,用“=”以外的东西来join集合是一个坏主意。