因此,当以 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/