我有以下要优化的SQL查询:
select table1.tiers as col1, table1.id_item as col2
from items table1
where (table1.tiers is not null)
and table1.tiers<>''
and table1.id_item = (select max(table2.id_item)
from items table2
where table1.tiers=table2.tiers)
and table1.n_version_item=(select max(table2.n_version_item)
from items table2
where table2.id_item=table1.id_item)
我尝试过:
select table1.tiers as col1, table1.id_item as col2
from items table1
where (table1.tiers is not null)
and table1.tiers<> ''
and CONCAT(table1.id_item,table1.n_version_item) = (select CONCAT(max(table2.id_item),max(table2.n_version_item))
from items table2
where table2.id_item=table1.id_item
and table1.tiers=table2.tiers)
但是我没有得到相同的结果。原始的第一个查询返回的行少于修改的行。请注意,表项具有主键(id,版本),并且每对夫妇都会影响一个层。
答案 0 :(得分:0)
使用函数时,它将阻止使用索引,因此CONCAT(table1.id_item,table1.n_version_item)
不会读取索引,除非其索引基于函数。但是,正如评论中提到的a_horse_with_no_name
一样,您可以使用以下代码:
select itm.tiers as col1, itm.id_item as col2
from items itm
where itm.tiers is not null
and itm.tiers<>''
and (itm.id_item , itm.n_version_item)= (select
max(item_sub.id_item),max(item_sub.n_version_item)
from items item_sub
where itm.tiers=item_sub.tiers)
然后,您必须检查查询的查询计划正在使用什么索引(您可以使用列tiers
和id_item
和n_version_item
上的其他索引来开始索引)
答案 1 :(得分:0)
我想你想要
class Team extends ActiveRecord {
public $team_id;
public $name;
public static $table = "teams";
public static $key = "team_id";
}
对于此版本,您希望在select i.tiers as col1, i.id_item as col2
from items i
where i.tiers is not null and -- redundant, but I'm leaving it in
i.tiers <> ''
(id_item, n_version_item) = (select i2.id_item, max(i2.n_version_item)
from items i2
where i2.tiers = i.tiers
order by i2.id_item desc, i2.n_version_item desc
limit 1
);
上建立索引。
答案 2 :(得分:0)
如果将列隐藏在“函数”(CONCAT
,DATE
等)中,则不能使用任何索引来提高性能。这样就无需考虑使用第二个版本。
与此相关的是“行构造器”的使用(请参阅a_horse_with_no_name的注释)。从历史上看,它们的优化很差;避免他们。我指的是WHERE (a,b) IN ( (1,2), ...)
或其他变体。
现在,让我们剖析
and table1.id_item = (select max(table2.id_item)
from items table2
where table1.tiers=table2.tiers)
table2
依次需要INDEX(tiers, id_item)
。这样,子查询就非常快。另一个子查询需要INDEX(id_item, n_version_item)
进入其余子查询:
and table1.id_item = <<value>>
现在让我们看一看
where (table1.tiers is not null)
and table1.tiers<>''
and table1.id_item = <<value>>
and table1.n_version_item = <<value>>
=
易于优化;其他不是。因此,让我们构建
INDEX(id_item, n_version_item, -- in either order
tiers) -- last
通过使用我指定的顺序,您可以避免还需要上面提到的INDEX(id_item, n_version_item)
。
(如果您提供SHOW CREATE TABLE
会有所帮助;我需要知道PK是什么,以及其他一些东西。)
作为奖励,这些索引将成为“覆盖索引”。
作为最后的音符(小调):
where (table1.tiers is not null)
and table1.tiers<>''
最好只根据您的指示来确定一种编码(NULL
与空字符串)。