mysql - 当使用 AJAX 以 JSON 格式从 MySQL 获取 2000 行时,TTFB 花费的时间太长

标签 mysql json ajax

因此,当以 JSON 格式获取大约 2000 个 MySQL 行时,在 AJAX 调用时返回数据大约需要 10 秒。
9 秒等待时间 (TTFB)
1秒下载内容...

有谁知道如何加快速度吗?

目前,我正在获取 MySQL 搜索的所有结果(没有任何 LIMIT),并且通过切片 JSON 数据来创建页面。

我猜减少负载的一种方法是通过 AJAX 调用发送页码并LIMIT MySQL 搜索,但真的没有其他方法吗?

下面是我原来的 MySQL 搜索查询。

这很复杂,因为我有一个搜索框,可以在标题、类别等多个字段中搜索数据库中的搜索关键字...
LIKE '%%' 的任何地方都是搜索词所在的位置。
但是,在选择类别时,它会在不同的位置过滤 MySQL 搜索:请参阅 LIKE '% health-and-beauty%'LIKE '%%' 保持为空。

SELECT wpp.ID, post_title, wp_terms.name AS category, wp_terms.slug AS slug, supplier_company, 
        GROUP_CONCAT(wp_terms.slug SEPARATOR ', ') AS allslug,
        GROUP_CONCAT(wp_terms.name SEPARATOR ', ') AS allcatname
        FROM wp_posts AS wpp
        LEFT JOIN wp_term_relationships ON wpp.ID = object_id
        LEFT JOIN wp_terms ON term_taxonomy_id = wp_terms.term_id
        LEFT JOIN wp_teleapo_supplier AS s ON wpp.post_author = s.ID



        /* BASIC SEARCH on normal fields */
        WHERE post_type = 'post' 


        GROUP BY wpp.ID

        /* SEARCH on CONCAT FIELDS*/
        HAVING

        (post_title LIKE '%%'
        OR allcatname LIKE '%%'
        OR allslug LIKE '%%'
        OR supplier_company LIKE '%%')
        AND (allslug LIKE '%health-and-beauty%'
        ) AND (allslug LIKE '%%'
        ) AND 

        /* ADD EXTRA SEARCH TAGS: */
        /* Language tag */
         allslug LIKE '%english%' 
        /* ..... tag */

        /* AND allslug LIKE '%......... %' */
        ORDER BY post_date DESC 

最佳答案

一些基础知识:

网络数据库基础知识

在幕后,几乎所有当代数据库都使用高度优化的 ISAM 存储格式。数据在与硬盘驱动器上的物理结构相对应的 block (称为页)中存储和检索。

表格是包含尽可能多行的页面的集合。

索引实际上是一个具有特殊契约的表:它仅包含您选择的列和对表中物理行的引用,并以有组织的方式维护以便快速搜索。由于索引较小并且是有序的,针对索引的搜索只需要扫描表所需时间的一小部分。在一个简单的情况下,在表中搜索一百万个大行以查找特定值可能需要长达三个小时,但从针对索引的冷启动开始,所需时间不会超过 40 毫秒。

那么 SQL 是如何与索引绑定(bind)的呢?

优化器位于您和底层物理数据库结构之间。根据您的联接和 where 子句,它会在查询中的各个实体之间查找成本最低的补丁。

这个查询怎么样?

查询中的联接如下:

LEFT JOIN wp_term_relationships ON wpp.ID = object_id
LEFT JOIN wp_terms ON term_taxonomy_id = wp_terms.term_id
LEFT JOIN wp_teleapo_supplier AS s ON wpp.post_author = s.ID

根据这些连接和常见实践,我希望索引位于:

wp_posts.object_id
wp_term_relationships.ID
wp_term_relationships.term_taxonomy_id 
wp_terms.term_id
wp_teleapo_supplier.id

主键、外键和唯一约束都是索引构造。如果您直接创建了索引或将这些列合并到任何这些构造中,那么您就拥有了索引。

您的“where”子句是:

WHERE post_type = 'post' 

除非“帖子”是一种罕见的帖子类型,否则这将带回系统中的几乎所有帖子。即使您在该列上有索引,它也不一定能给您带来任何好处,因为它的选择性太差了。

最后,您应用了“Having”子句,该子句应用于前面查询的结果集。

       HAVING

    (post_title LIKE '%%'
    OR allcatname LIKE '%%'
    OR allslug LIKE '%%'
    OR supplier_company LIKE '%%')
    AND (allslug LIKE '%health-and-beauty%'
    ) AND (allslug LIKE '%%'
    ) AND 

    /* ADD EXTRA SEARCH TAGS: */
    /* Language tag */
     allslug LIKE '%english%' 
    /* ..... tag */

因此,在您的查询中,您已有效地选择了每个帖子及其附加的所有内容,然后您尝试对每一行上的这些列运行部分文本模式匹配。

建议的解决方案:

是时候退后 10 并弃踢了。这是一个需要文本搜索引擎来获得正确选择性的问题,而不是关系系统。

MySQL 有一个文本搜索引擎,完整记录在 https://dev.mysql.com/doc/refman/5.5/en/fulltext-search.html

设置文本搜索索引,然后反转查询,以便最高选择性出现在联接或 where 子句中,然后将having应用于您实际需要的几行。

或者,如果您的数据集足够大,您可能需要寻找更强大的解决方案来进行严肃的文本搜索。

关于mysql - 当使用 AJAX 以 JSON 格式从 MySQL 获取 2000 行时,TTFB 花费的时间太长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36050933/

相关文章:

arrays - Angular -HttpClient : Map Get method object result to array property

ios - Object Swift 中数组中的对象

json - logstash_forwarder已连接到Lostash服务器IP,但从未收到事件

mysql - 实现复合索引

mysql - 更改列中数据的文本文本转换? [SQL]

javascript - 选择框 onchange 时更新 mysql 表中的值

php - 将编号行/序列号添加到数据库查询结果集中

javascript - 如何在 JS/Ajax 中每秒拉取 PHP 函数

javascript - 动态生成页面中的事件处理

jquery - 将具有多个属性的 JSON 对象转换为 html 元素