我使用的是laravel php框架。
假设我有这样的问题:
public function order($orderby){
\DB::connection()->disableQueryLog();
if($orderby == "level"){
$clan = Clans::orderBy('level', 'DESC')
->orderBy('exp', 'DESC')
->paginate(100,['id', 'clanid', 'name', 'level', 'exp', 'warwinpercent', 'warswon', 'playercount', 'score']);
}elseif($orderby == "score"){
$clan = Clans::orderBy('score', 'DESC')
->paginate(100,['id', 'clanid', 'name', 'level', 'exp', 'warwinpercent', 'warswon', 'playercount', 'score']);
}elseif($orderby == "warwinpercent"){
$clan = Clans::orderBy('warwinpercent', 'DESC')
->where('warswon', '>=', '100')
->paginate(100,['id', 'clanid', 'name', 'level', 'exp', 'warwinpercent', 'warswon', 'playercount', 'score']);
}else
$clan = Clans::paginate(100,['id', 'clanid', 'name', 'level', 'exp', 'warwinpercent', 'warswon', 'playercount', 'score']);
\DB::connection()->enableQueryLog();
return view('clans.index')->with('clan', $clan);
}
跑步大约需要10-15秒。
我有一个这样的:
public function index(){
$clan = Clans::orderBy('clanid', 'ASC')
->paginate(100,['id', 'clanid', 'name', 'level', 'exp', 'warwinpercent', 'warswon', 'playercount', 'score']);
return view('clans.index')->with('clan', $clan);
}
几乎立刻就能装上。
为什么前三个要比最后一个花这么长时间?我为表中需要搜索的所有变量添加了索引,但它仍需要很长时间才能工作。我需要在mysql方面做些什么来重建索引吗?我已经尝试过优化表,并且多次重新启动mysql服务。
如果无法加快速度,那么有没有一种简单的方法可以在加载页面时向用户显示加载动画?
谢谢!
更新
下面是快速查询的解释结果:
explain extended select `id`, `clanid`, `name`, `level`, `exp`, `warwinpercent`, `warswon`, `playercount`, `score` from `clans` order by `clanid` asc limit 100 offset 0
这是
orderBy level
查询的解释结果。explain extended select `id`, `clanid`, `name`, `level`, `exp`, `warwinpercent`, `warswon`, `playercount`, `score` from `clans` order by `level` desc, `exp` desc limit 100 offset 0
这是
SHOW INDEX FROM clans
结果。更新2
我还有一个代码,它在
name
列中搜索字符串。public function clans(){
if((isset($_GET['search'])) && $_GET['search'] != ""){
$search = $_GET['search'];
$result = Clans::where('name', 'LIKE', '%'.$search.'%')->paginate(100,['id', 'clanid', 'name', 'level', 'exp', 'warwinpercent', 'warswon', 'playercount', 'score']);
$data = array(
'result' => $result,
'search' => $search
);
return view('search.clans')->with($data);
}else
return view('errors.1')->with('message', 'You entered an invalid search term');
}
再次加载可能需要几秒钟。
解释查询:
explain extended select `id`, `clanid`, `name`, `level`, `exp`, `warwinpercent`, `warswon`, `playercount`, `score` from `clans` where `name` LIKE '%lol%' limit 100 offset 0
最佳答案
查询2的问题(查询1看起来很好)。但是有了两个索引,尽管在级别上有一个索引,但基数太高,mysql放弃了它。行数170K,基数159K
从题为How MySQL Uses Indexes的手册页:
索引对于查询小表或大表不太重要
报表查询处理大多数或所有行的位置。当一个查询
需要访问大多数行,按顺序读取比
通过索引工作。顺序读取使磁盘查找最小化,甚至
如果不是查询所需的所有行。见第8.2.1.16节,
“如何避免全表扫描”了解详细信息。
综合指数
复合(Multi-column)索引是作为组合在两列或更多列上的索引。可以是唯一的,也可以不是。
CREATE UNIQUE INDEX `thing_my_composite` ON thing (position,email,dob); -- forbid dupes hereafter
覆盖指数
覆盖索引是一种查询可以通过快速浏览索引b树来解决的索引,而不需要查找实际的表数据页。这是速度的终极涅盘。Percona关于它的快速文章。
全文搜索(基于操作注释)
在Full-Text Search Functions的本手册中,以下是摘录:
MySQL支持全文索引和搜索:
mysql中的全文索引是full text类型的索引。
全文索引只能与myisam表一起使用。(在mysql 5.6中
此外,它们还可以用于innodb表。)全文索引
只能为char、varchar或text列创建。
可以在CREATE TABLE语句中给出全文索引定义
创建表时,或稍后使用alter table或create添加表时
索引。
对于大型数据集,将数据加载到表中要快得多
没有全文索引,然后在此之后创建索引的
将数据加载到具有现有全文索引的表中。