首页 > 解决方案 > 如何使用全文加速我的 MySQL 查询

问题描述

我有 2 张桌子。

  1. special_order(订单表)- 有 420 000 个数据
  2. 与 order_id 链接到 special_order 表的 special_order_product(产品表)。有 1 000 000 个数据

数据库存储引擎:InnoDB

我试图根据带有左连接的关键字查找具有产品的订单。查询需要 10-15 秒。另外,我对 product_link 列使用全文索引其他索引(special_order.id,special_order_product.order_id)

SPECIAL_ORDER TABLE: 表结构

特殊订单产品表: 表结构

查询:

SELECT distinct(special_order.id), special_order.admin_id, special_order.user_id, 
  special_order.total_price, special_order.created_at, special_order.updated_at 
FROM special_order LEFT JOIN special_order_product 
  ON special_order.id = special_order_product.order_id 
WHERE MATCH(product_link) AGAINST ('trendyol' IN BOOLEAN MODE) 
order by created_at desc limit 30

结果:集合 30 行(15.730 秒)

查询解释:查询 解释

特殊订单表上的索引: 特殊订单表索引

special_order_product 表上的索引: 在此处输入图像描述

标签: mysqloptimizationfull-text-searchinnodb

解决方案


  • DISTINCT不是函数;它将删除一组SELECT列。
  • 您似乎想找到product_link值,但您说它是选项 ( LEFT)。也许LEFT是错的?

建议改写如下:

SELECT  so.id, so.admin_id, so.user_id, so.total_price,
        so.created_at, so.updated_at
    FROM ( SELECT p.order_id 
             FROM special_order_product AS p
             WHERE  MATCH(p.product_link) AGAINST ('trendyol' IN BOOLEAN MODE)
             order by  p.created_at desc
             limit  30
         ) AS p2
    JOIN  special_order AS so  ON so.id = p2.order_id
    order by  so.created_at desc

笔记:

  • 派生表(子查询)专注于获取 30 个项目,然后停止。
  • 因此,只有 30 次探测so
  • 我认为不需要重复数据删除。
  • 重复(某种程度)是因为子查询在ORDER BY被外部查询使用时没有顺序。但LIMIT需要对数据进行排序。

需要的索引(其他的在这里没用):

p: FULLTEXT(product_link)
so: (id)  -- the PRIMARY KEY

推荐阅读