2015-12-02 97 views
0

我有一个特定的结构,我想要重写,以便它运行更快的MySQL查询。目前运行速度很慢,需要大约255秒才能执行。如果我删除了连接,它将在10秒内运行<。它的目的是一次从表A获得100行记录,只要用户希望看到更多的行。制作限制X,Y MySQL查询连接运行更快

我怀疑这个查询花了很长时间,因为它在连接上发现的不止是前100行。这是真的吗?如果是这样,有没有办法在从主表中获取行之后重写查询来完成连接?

数据来自'主'表A,它具有日期时间字段(START_TIME)和多个带字符串值的表的外键(表,B,C,D)。

表A有250万行。表B有600K行。 表A在START_TIME上有一个索引。表B有一个ID值的索引。

这是查询的基本形式。我不想在START_TIME上设置上限,因为我总是希望从查询中获取100条记录。我使用了少于100条记录的响应来指示数据库中没有更多记录。

SELECT 
    A.START_TIME, A.F1, A.F2, B.STRING 
FROM 
    A 
    INNER JOIN B ON A.B_ID = B.ID 
WHERE 
    A.START_TIME >= '2015-03-22 05:23:44' 
LIMIT 0, 100; 

这里是解释。对不起,格式为:

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra 
1, SIMPLE, B, index, PRIMARY, FSN, 95, , 1, Using index; Using temporary; Using filesort 
1, SIMPLE, A, ref, A_ix_B_ID,A_ix_C, A_ix_B_ID, 4, ag100_a$$burnaby.B.ID, 2, Using where 
+0

您可以使用'ctrl-k'将文本格式设置为代码。 –

+0

现在你必须尝试每次添加一个表格http://importblogkit.com/2015/05/how-do-you-eat-an-elephant/你应该尝试每一个选择类型索引 –

+0

这里一次添加一个表的结果:仅表A:8.7秒,表A和B:255秒。问题仍然存在,我的原始问题仍然存在:是否有一种重构此查询的方式,以便在从表A检索记录之后完成连接。这是非常重要的,因为这是一个非常常见的查询。 – user3341576

回答

0

你必须提供解释计划,以便我们可以帮助你更好。

https://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html

但是对于你的描述,你仍然需要索引。

表A旁START_TIME为每个索引需要加入字段B_id, C_id and D_id,也许使用复合指数对于所有4个可变会更好

CREATE INDEX A_Bid_idx ON A (B_id); 
CREATE INDEX A_Cid_idx ON A (C_id); 
CREATE INDEX A_Did_idx ON A (D_id); 

OR 

CREATE INDEX A_Full_idx ON A (B_id,C_id, D_id, START_TIME); 

表C和d还需要C.ID and D.ID索引。如果他们使用的复合指数

(C.ID, C.STRING) and 
    (D.ID, D.STRING) 

    CREATE INDEX C_id_idx ON C (ID); 
    CREATE INDEX D_id_idx ON D (ID); 

    OR 

    CREATE INDEX C_id_string_idx ON C (ID, STRING); 
    CREATE INDEX D_id_string_idx ON C (ID, STRING); 

这样分贝不必须做一个查找找到asociated的ID

+0

关于更好的解释,你还想知道什么?但是,在发现100条记录之后,通过对连接进行的最大节省时间不是最大的节省时间吗?我会添加上面建议的索引,然后重试。 – user3341576

+0

正如我所说,你仍然需要一些索引。你必须向我们展示解释计划,看看问题出在哪里http://use-the-index-luke.com/sql/explain-plan/mysql/getting-an-execution-plan –

+0

请帮助我。我不知道要给你什么其他信息。 – user3341576

0
SELECT A.START_TIME, A.F1, A.F2, 
     (SELECT STRING 
      FROM B 
      WHERE A.B_ID = B.ID 
    ) AS String 
    FROM A 
    WHERE A.START_TIME >= '2015-03-22 05:23:44' 
    ORDER BY START_TIME 
    LIMIT 0, 100; 

可能会跑得更快的字符串值,甚至会更好。从A'被迫'使用INDEX(START_TIME)

请提供SHOW CREATE TABLE这两个表;我想检查数据类型等。