mysql查询速度慢,需要帮助优化
解释问题:mysql查询速度慢,需要帮助优化,mysql,sql,Mysql,Sql,解释问题: table1 time userid id1 id2 9/1/2014 3:30 user1 123 555 9/1/2014 3:32 user1 123 555 9/1/2014 3:13 user1 123 555 9/1/2014 3:15 user1 123 555 9/1/2014 3:38 user2 321 555 9/1/2014 3:21 user2 321 555 9/1/2014 3:
table1
time userid id1 id2
9/1/2014 3:30 user1 123 555
9/1/2014 3:32 user1 123 555
9/1/2014 3:13 user1 123 555
9/1/2014 3:15 user1 123 555
9/1/2014 3:38 user2 321 555
9/1/2014 3:21 user2 321 555
9/1/2014 3:38 user2 456 666
9/1/2014 3:21 user2 456 666
table2
id1 orderid
321 order1
123 order2
我的table1大约有10亿行,table2是一个有20k行的查找表,而order 555大约有1亿行。
id2约占表1总量的10%。表2基本上是包含所有id1的查找表。id1->orderid具有多对一关系。换句话说,一个id1只属于一个orderid。
表2和表1除了userid之外没有空值
我想计算每个orderid的唯一用户
我的查询运行时间很长(在5小时内没有完成,所以我停止了它),除了索引之外,我不知道如何优化它。我在表2.id1上有索引
select_type table type possible index key key_len ref row Extra
SIMPLE table1 ALL 934420 Using where; Using temporary; Using filesort
SIMPLE table2 ref lookupindex lookupindex 33 table1.id1 1
mysql是先执行左join还是先执行where语句?应该将订单555存储到不同的表中,然后运行查询 问题在于你独特的操作,那一个非常昂贵。您可以通过在userid上放置一个索引来提高效率,这两个键也应该有一个索引。我不确定您在功能上想做什么,但可能还有其他方法可供选择。问题在于您的独特操作,该操作非常昂贵。您可以通过在userid上放置一个索引来提高效率,这两个键也应该有一个索引。我不确定您在功能上想做什么,但可能还有其他方法可供选择。问题在于您的独特操作,该操作非常昂贵。您可以通过在userid上放置一个索引来提高效率,这两个键也应该有一个索引。我不确定您在功能上想做什么,但可能还有其他方法可供选择。问题在于您的独特操作,该操作非常昂贵。您可以通过在userid上放置一个索引来提高效率,这两个键也应该有一个索引。我不确定您试图在功能上做些什么,但也可能有其他选择。这基本上是您的问题:
select table2.orderid, count(distinct userid)
from table1 left join table2 on table1.id1 = table2.id1
where table1.id2="555"
group by table2.orderid
首先,您可能不需要左联接
,因为您是按第二个表中的一列进行分组的。如果表1
相当大,这可能会有很大帮助。因此,在不使用该联接的情况下编写查询:
select t2.orderid, count(distinct t1.userid)
from table1 t1 left join
table2 t2
on t1.id1 = t2.id1
where t1.id2 = 555
group by t2.orderid;
其次,您需要在table1(id2,id1,userid)
和table2(id1,orderid)
上建立索引
根据数据的性质,可能还有其他一些优化。例如,
table1
是否包含多个userid
,或者distinct
是否是join
的工件?这基本上是您的查询:
select table2.orderid, count(distinct userid)
from table1 left join table2 on table1.id1 = table2.id1
where table1.id2="555"
group by table2.orderid
首先,您可能不需要左联接
,因为您是按第二个表中的一列进行分组的。如果表1
相当大,这可能会有很大帮助。因此,在不使用该联接的情况下编写查询:
select t2.orderid, count(distinct t1.userid)
from table1 t1 left join
table2 t2
on t1.id1 = t2.id1
where t1.id2 = 555
group by t2.orderid;
其次,您需要在table1(id2,id1,userid)
和table2(id1,orderid)
上建立索引
根据数据的性质,可能还有其他一些优化。例如,
table1
是否包含多个userid
,或者distinct
是否是join
的工件?这基本上是您的查询:
select table2.orderid, count(distinct userid)
from table1 left join table2 on table1.id1 = table2.id1
where table1.id2="555"
group by table2.orderid
首先,您可能不需要左联接
,因为您是按第二个表中的一列进行分组的。如果表1
相当大,这可能会有很大帮助。因此,在不使用该联接的情况下编写查询:
select t2.orderid, count(distinct t1.userid)
from table1 t1 left join
table2 t2
on t1.id1 = t2.id1
where t1.id2 = 555
group by t2.orderid;
其次,您需要在table1(id2,id1,userid)
和table2(id1,orderid)
上建立索引
根据数据的性质,可能还有其他一些优化。例如,
table1
是否包含多个userid
,或者distinct
是否是join
的工件?这基本上是您的查询:
select table2.orderid, count(distinct userid)
from table1 left join table2 on table1.id1 = table2.id1
where table1.id2="555"
group by table2.orderid
首先,您可能不需要左联接
,因为您是按第二个表中的一列进行分组的。如果表1
相当大,这可能会有很大帮助。因此,在不使用该联接的情况下编写查询:
select t2.orderid, count(distinct t1.userid)
from table1 t1 left join
table2 t2
on t1.id1 = t2.id1
where t1.id2 = 555
group by t2.orderid;
其次,您需要在table1(id2,id1,userid)
和table2(id1,orderid)
上建立索引
根据数据的性质,可能还有其他一些优化。例如,
table1
是否包含多个userid
,或者distinct
是否是join
的工件?首先,计算所有不同的值userid和id1(无join),然后将table1中的计数值与table2合并
select t2.orderid, count(distinct t1.userid)
from table1 t1 join
table2 t2
on t1.id1 = t2.id1
where t1.id2 = 555
group by t2.orderid;
首先,计算所有不同的值userid和id1(无连接),然后将表1中的计数值与表2连接起来
select t2.orderid, count(distinct t1.userid)
from table1 t1 join
table2 t2
on t1.id1 = t2.id1
where t1.id2 = 555
group by t2.orderid;
首先,计算所有不同的值userid和id1(无连接),然后将表1中的计数值与表2连接起来
select t2.orderid, count(distinct t1.userid)
from table1 t1 join
table2 t2
on t1.id1 = t2.id1
where t1.id2 = 555
group by t2.orderid;
首先,计算所有不同的值userid和id1(无连接),然后将表1中的计数值与表2连接起来
select t2.orderid, count(distinct t1.userid)
from table1 t1 join
table2 t2
on t1.id1 = t2.id1
where t1.id2 = 555
group by t2.orderid;
Q:mysql是先执行左join还是先执行where语句?是否应将订单555存储到不同的表中,然后运行查询? 理论上,优化器可以自由选择产生指定结果的任何执行计划。优化器应该足够聪明,能够选择它认为最有效的操作顺序 实际上,我们编写语句的方式以及我们提供的索引对MySQL可用的选项有很大的影响
要查看MySQL选择的执行计划,我们可以使用
EXPLAIN
。这向我们展示了MySQL将执行的操作的摘要
有了适当的索引,MySQL可以获得更高效的访问路径
没有看到EXPLAIN输出,或表的定义,以及可用的索引,我们只是猜测
考虑到这个语句的速度非常慢,我们将大胆猜测,合适的索引不可用,其次,MySQL在