好吧,RBarryYoung 你问我关于你得到的参考/分析
此参考/分析基于关闭 MySQL 服务器的文档/源代码分析
INSERT Into ArticleCategories(A_ID,C_ID)
SELECT A_ID,C_ID From Articles
在包含许多行的大型 Articles 表上,此副本会将 CPU 中的一个核心推至 100% 负载,并会创建一个基于磁盘的临时表,这会降低整个 MySQL 的性能,因为磁盘会因该副本而受到压力.
如果这是一个一次性的过程,那还不错,但是如果您每次都运行它,请进行数学计算..
SELECT a_id,name,Description
FROM Articles
WHERE EXISTS( Select *
From ArticleCategories
INNER JOIN Category ON ArticleCategories.c_id=Category.id
WHERE Articles.a_id=ArticleCategories.a_id
AND Category.cat_name LIKE '%'+{$match}+'%'
)
注意不要把 sqlfriddle 上的执行时间当成是一个繁忙的服务器,而且时间变化很大以做出一个好的陈述,但是看看 View Execution Plan 有什么要说的
见http://sqlfiddle.com/#!2/48817/21 演示
如果您有一个包含许多记录的大型 Articles 表,这两个查询总是会触发对表 Articles 和两个 DEPENDENT SUBQUERYS 的完整表扫描。
这意味着即使您只需要该类别中的文章,性能也取决于文章行数。
Select *
From ArticleCategories
INNER JOIN Category ON ArticleCategories.c_id=Category.id
WHERE Articles.a_id=ArticleCategories.a_id
AND Category.cat_name LIKE '%'+{$match}+'%'
此查询是内部子查询,但当您尝试运行它时,MySQL 无法运行,因为它依赖于 Articles 表的值,因此这是相关子查询。一个子查询类型,将为外部查询处理的每一行计算一次。确实不好
还有更多方法可以重写 RBarryYoung 查询,我将展示一个。
即使使用 LIKE 运算符,INNER JOIN 方式也更有效
注意,我养成了一个习惯,即我从记录数最少的表开始,如果你从表 Articles 开始,我会按照我的方式向上工作,如果 MySQL 优化器选择正确的计划,执行将是相同的。 .
SELECT
Articles.a_id
, Articles.name
, Articles.description
FROM
Category
INNER JOIN
ArticleCategories
ON
Category.id = ArticleCategories.c_id
INNER JOIN
Articles
ON
ArticleCategories.a_id = Articles.a_id
WHERE
cat_name LIKE '%php%';
;
请参阅http://sqlfiddle.com/#!2/43451/23 以查看演示请注意,这看起来更糟,因为它看起来需要检查更多行
请注意,如果 Article 表的记录数较少,RBarryYoung EXIST 方式和 INNER JOIN 方式将根据执行时间或多或少地执行相同的操作,并且更多证据表明当记录数变大时,INNER JOIN 方式可以更好地扩展
http://sqlfiddle.com/#!2/c11f3/1 EXISTS oeps 现在需要检查更多文章记录(即使它们没有与 ArticleCategories 表链接),因此现在查询效率较低
http://sqlfiddle.com/#!2/7aa74/8INNER JOIN 跟第一个demo一样的解释方案
关于扩展的额外说明,当您还想 ORDER BY 或 GROUP BY 时,NOT EXIST 方式更有可能创建一个基于磁盘的临时表,这会降低 MySQL 的性能
让我们也分析 EXIST 方式和 INNER JOIN 方式的 LIKE '%php%' vs = 'php'
EXIST 方式
http://sqlfiddle.com/#!2/48817/21/http://sqlfiddle.com/#!2/c11f3/1(更多文章)解释告诉我两种模式或多或少相同,但 'php' 应该快一点,因为 TYPE 列中的 const 类型与 ref 不同,但 LIKE %php%将使用更多 CPU,因为需要运行字符串比较算法。
INNER JOIN 方式
http://sqlfiddle.com/#!2/43451/23/http://sqlfiddle.com/#!2/7aa74/8(更多文章)解释告诉我 LIKE '%php%' 应该更慢,因为需要再分析 3 行,但在这种情况下不会令人震惊(你可以看到索引是并没有真正以最佳方式使用)。
RBarryYoung 方法有效,但至少不能在 MySQL 服务器上保持性能
见http://sqlfiddle.com/#!2/b2bd9/1 或http://sqlfiddle.com/#!2/34ea7/1
对于将在具有大量记录的大型表上进行扩展的示例,这是主题启动者所需要的