优化MySQL FULLTEXT和邻近搜索查询

时间:2016-10-09 14:16:38

标签: php mysql laravel relational-database

考虑下面的Schema::create('adverts', function (Blueprint $table) { $table->increments('id'); //PRIMARY KEY $table->string('name', 150); //VARCHAR $table->text('description'); //TEXT $table->integer('city_id')->nullable(); $table->foreign('city_id')->references('id')->on('cities'); $table->timestamps(); }); 表(使用Laravel创建,但代码非常自我解释):

adverts

FULLTEXT表有更多列,但这些是现在必需的。我希望用户能够找到带有文本搜索功能的广告,因此我添加了以下ALTER TABLE posts ADD FULLTEXT search(name, description) 索引:

city_id

正如您所看到的,每个广告还有一个adverts外键,用户可以在city以及给定半径范围内的城市中搜索radius。为此,我有一个| city_A | city_B |distance| ---------------------------------- | 1 | 2 | 30 | | 2 | 1 | 30 | 表,其中包含城市对的记录以及彼此之间的距离:

radius

adverts表包含大约7 000 000条记录,并且所有列都已编制索引。我在Advert::whereRaw('MATCH(name, description) AGAINST(? IN BOOLEAN MODE)', [$term]) ->join('radius', function ($join) use ($radius, $id){ $join->on('radius.secondary_id','=', 'posts.city_id'); })->where('radius.primary_id', $id) ->whereBetween('radius.radius', [0,$radius]); 表播种了大约10万个假记录(描述大约是700个字符)。搜索广告时,我执行以下Laravel查询:

SLECT * FROM `adverts` 
INNER JOIN `radius` on `radius`.`city_B` = `posts`.`city_id` 
WHERE MATCH(name, description) AGAINST(? IN BOOLEAN MODE) 
AND `radius`.`city_A` = ? 
AND `radius`.`radius` between ? and ?
ORDER BY `created_at` desc 
LIMIT 20

在SQL中,这转换为:

adverts

好的,因为我说FULLTEXT表有更多列,但在执行搜索查询时似乎没有造成重大问题。然而,一旦我将MATCH术语搜索与城市邻近搜索结合起来,查询在我的本地主机上执行需要相当长的时间 - 大约10-15秒。似乎在整个adverts表上执行radius工作正常,CPU: Intel Core i5 3450 @ 3.10GHz Quad RAM: 8,00GB Dual-Channel DDR3 @ 665MHz HDD: Seagate ST3320613AS ATA Device (SATA) 7200RPM 16MB Cache 搜索工作正常但是这样组合会导致响应相当慢。

我是否可以采取一些措施来改进表格或查询语句,或者这是MySQL无法跟上的情况?

我的记录规范:

+----+-------------+-------+------+---------------+-----+---------+-----+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-----+---------+--------+---+--+
| 1  |    SIMPLE   |adverts|fulltxt|adverts_city_id_foreign,| search | 0 |  | 1 | Using where; Using filesort |
|    |             |       |       | search                 |        |   |
------------------------------------------------------------------------------------------
| 1  |   SIMPLE   | radius | ref  | city_A_index,| city_A_index| 5 | test_db.adverts.city_id | 1417 | Using where |
|    |            |        |      | city_B_index,|             |   |
|    |            |        |      | distances_ind|             |   |
+----+------------+--------+------+--------------+-------------+---+---+---+---+

编辑:MySQL解释内连接查询:

UPDATE STATEMENT

0 个答案:

没有答案
相关问题