如何使用索引优化此MySql表以获得搜索速度?

时间:2016-10-09 10:29:41

标签: mysql indexing database-indexes

作为一名MySql业余爱好者,我想就表优化和索引的使用提出一些建议。

考虑一个包含用户发布的广告的表格。该表具有以下结构(这是一个Laravel实现,但我认为代码是不言自明的):

Schema::create('advertisements', function (Blueprint $table) {
        $table->increments('id');     //PRIMARY KEY AUTOINCREMENTS
        $table->text('images');       //TEXT
        $table->string('name', 150);  //VARCHAR(150)
        $table->string('slug');       //VARCHAR(255)
        $table->text('description');
        $table->string('offer_type',7)->nullable()->index();
        $table->float('price')->nullable();
        $table->string('deal_type')->nullable()->index();
        $table->char('price_period',1)->nullable()->index();
        $table->float('price_per_day')->nullable();
        $table->float('deposit')->nullable();

        $table->integer('category_id')->unsigned()->index();
        $table->foreign('category_id')->references('id')->on('categories');

        $table->integer('author_id')->unsigned()->nullable();
        $table->foreign('author_id')->references('id')->on('users');

        $table->timestamps();
    });

网站上的用户可以使用多个条件搜索上表中的广告,例如:price范围,offer_typeprice_perioddeal_type

如您所见,我已将offer_typeprice_perioddeal_type列编入索引。根据我的理解,这会导致DB在这些列中创建值的BTREE索引。

但是,这些值总是来自预定义的集合: 例如,price_period始终是以下之一:NULL, h, d, w, m, y(小时,天,周,月,年)。 deal_type列始终为offerdemand

问题: 如果我有一组列只包含来自预定义的小范围值的值,那么创建单独的更好(性能方面)他们使用表并使用外键而不是索引列?编辑:经过进一步的研究我现在意识到,外键只是一个引用工具,而不是性能工具,它们可以(也应该)被编入索引。但是,索引的外键(一个数字)是否比索引短字符串表现更好?

1 个答案:

答案 0 :(得分:1)

索引标志和其他低基数列通常是无用的。例如,如果表的一半具有某个标志值,则更快忽略该标志上的索引并只扫描整个表。

我们确实需要查看查询以判断需要哪些索引。根据你的提示,无论如何我都要刺...

“如:价格范围,offer_type,price_period或deal_type” - 我假设用户会给出最低和最高价格?然后让我们用price_per_day构建一个“复合”索引结尾。他们是否总是指定所有其他三列?每列的单个值?如果对以上所有都是肯定的,那么这个综合指数是最佳的:

INDEX(over_types, price_period, deal_type, price_per_day)

(前3列可以按任意顺序排列,但应用于该范围的内容需要最后。)

如果用户可能只包含其中一些标志,和/或可能包含多个值,那么它就会变得更加混乱。观察用户要求的内容,并根据常见查询定制额外的索引。使用此index cookbook来帮助构建它们。