PHP加速MySql查询

时间:2015-10-30 17:52:57

标签: php mysql performance laravel laravel-5

我正在使用Laravel PHP Framework。

说我有这样的疑问:

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

1 个答案:

答案 0 :(得分:0)

查询2的问题(查询1看起来很好)。但有两个,虽然你有一个级别的索引,基数是如此之高,以至于mysql放弃它。行数170K,基数159k

从标题为How MySQL Uses Indexes的手册页

  

索引对于小型表或大型表的查询不太重要   报表查询处理大多数或所有行的位置。当一个查询   需要访问大多数行,顺序读取比快   通过索引工作。顺序读取可以最大限度地减少磁盘搜索   如果不是查询所需的所有行。见8.2.1.16节,   “如何避免全表扫描”了解详情。

综合指数

复合(Multi-column)索引是作为组合的2列或更多列的索引。可以是独特的,也可以不是。

CREATE UNIQUE INDEX `thing_my_composite` ON thing (position,email,dob); -- forbid dupes hereafter

覆盖指数

覆盖索引是一种可以通过索引b树快速漫步来解析查询的索引,需要查找实际表数据页面。这些是速度的终极天堂。 Percona快速撰写文章。

全文搜索(基于OP评论)

Full-Text Search Functions的手册页上,摘录如下:

  

MySQL支持全文索引和搜索:

     

MySQL中的全文索引是FULLTEXT类型的索引。

     

全文索引只能用于MyISAM表。 (在MySQL 5.6中   并且,它们也可以与InnoDB表一起使用。)全文索引   只能为CHAR,VARCHAR或TEXT列创建。

     

可以在CREATE TABLE语句中给出FULLTEXT索引定义   创建表时,或稍后使用ALTER TABLE或CREATE添加   INDEX。

     

对于大型数据集,将数据加载到表中要快得多   那个没有FULLTEXT索引,然后在那之后创建索引   将数据加载到具有现有FULLTEXT索引的表中。