perf: mysql递归查询兼容处理

This commit is contained in:
2025-07-10 17:30:01 +08:00
parent 7e22eccd02
commit 343a77ec73
6 changed files with 139 additions and 54 deletions

View File

@@ -8,6 +8,7 @@ DB_PASS = 14Xi17NIK8V2qAXE8oMataHEsaR8lE
DB_PORT = 3306 DB_PORT = 3306
DB_CHARSET = utf8mb4 DB_CHARSET = utf8mb4
DB_PREFIX = ow_ DB_PREFIX = ow_
DB_VERSION = 8
DEFAULT_LANG = zh-cn DEFAULT_LANG = zh-cn

View File

@@ -64,19 +64,36 @@ class ArticleCategoryValidate extends Validate
if ($value == 0) { if ($value == 0) {
return true; return true;
} }
$children = [];
$table_name = (new ArticleCategoryModel)->getTable(); $table_name = (new ArticleCategoryModel)->getTable();
$children = Db::query( if (env('DB_VERSION', '5') == '8') {
preg_replace( $children = Db::query(
'/\s+/u', preg_replace(
' ', '/\s+/u',
"WITH RECURSIVE article_tree_by AS ( ' ',
SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']} "WITH RECURSIVE article_tree_by AS (
UNION ALL SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']}
SELECT k.id, k.pid FROM $table_name k INNER JOIN article_tree_by t ON t.id = k.pid UNION ALL
SELECT k.id, k.pid FROM $table_name k INNER JOIN article_tree_by t ON t.id = k.pid
)
SELECT id FROM article_tree_by WHERE id <> {$data['id']};"
) )
SELECT id FROM article_tree_by WHERE id <> {$data['id']};" );
) } else {
); $children = \think\facade\Db::query("
SELECT t2.id
FROM (
SELECT
@r AS _id, (SELECT @r := GROUP_CONCAT(id) FROM $table_name WHERE FIND_IN_SET(pid, _id)) AS parent_id
FROM
(SELECT @r := {$data['id']}) vars, $table_name h
WHERE @r <> 0) t1
JOIN $table_name t2
ON FIND_IN_SET(t2.pid, t1._id)
ORDER BY t2.id;
");
}
if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) { if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) {
return false; return false;
} }

View File

@@ -49,19 +49,36 @@ class AttachmentCategoryValidate extends Validate
if ($value == 0) { if ($value == 0) {
return true; return true;
} }
$children = [];
$table_name = (new AttachmentCategoryModel)->getTable(); $table_name = (new AttachmentCategoryModel)->getTable();
$children = Db::query( if (env('DB_VERSION', '5') == '8') {
preg_replace( $children = Db::query(
'/\s+/u', preg_replace(
' ', '/\s+/u',
"WITH RECURSIVE attachment_tree_by AS ( ' ',
SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']} "WITH RECURSIVE attachment_tree_by AS (
UNION ALL SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']}
SELECT k.id, k.pid FROM $table_name k INNER JOIN attachment_tree_by t ON t.id = k.pid UNION ALL
SELECT k.id, k.pid FROM $table_name k INNER JOIN attachment_tree_by t ON t.id = k.pid
)
SELECT id FROM attachment_tree_by WHERE id <> {$data['id']};"
) )
SELECT id FROM attachment_tree_by WHERE id <> {$data['id']};" );
) } else {
); $children = \think\facade\Db::query("
SELECT t2.id
FROM (
SELECT
@r AS _id, (SELECT @r := GROUP_CONCAT(id) FROM $table_name WHERE FIND_IN_SET(pid, _id)) AS parent_id
FROM
(SELECT @r := {$data['id']}) vars, $table_name h
WHERE @r <> 0) t1
JOIN $table_name t2
ON FIND_IN_SET(t2.pid, t1._id)
ORDER BY t2.id;
");
}
if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) { if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) {
return false; return false;
} }

View File

@@ -61,19 +61,36 @@ class NavigationItemValidate extends Validate
if ($value == 0) { if ($value == 0) {
return true; return true;
} }
$children = [];
$table_name = (new SysNavigationItemModel)->getTable(); $table_name = (new SysNavigationItemModel)->getTable();
$children = Db::query( if (env('DB_VERSION', '5') == '8') {
preg_replace( $children = Db::query(
'/\s+/u', preg_replace(
' ', '/\s+/u',
"WITH RECURSIVE tree_by AS ( ' ',
SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']} "WITH RECURSIVE tree_by AS (
UNION ALL SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']}
SELECT k.id, k.pid FROM $table_name k INNER JOIN tree_by t ON t.id = k.pid UNION ALL
SELECT k.id, k.pid FROM $table_name k INNER JOIN tree_by t ON t.id = k.pid
)
SELECT id FROM tree_by WHERE id <> {$data['id']};"
) )
SELECT id FROM tree_by WHERE id <> {$data['id']};" );
) } else {
); $children = \think\facade\Db::query("
SELECT t2.id
FROM (
SELECT
@r AS _id, (SELECT @r := GROUP_CONCAT(id) FROM $table_name WHERE FIND_IN_SET(pid, _id)) AS parent_id
FROM
(SELECT @r := {$data['id']}) vars, $table_name h
WHERE @r <> 0) t1
JOIN $table_name t2
ON FIND_IN_SET(t2.pid, t1._id)
ORDER BY t2.id;
");
}
if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) { if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) {
return false; return false;
} }

View File

@@ -74,19 +74,36 @@ class SysMenuValidate extends Validate
if ($value == 0) { if ($value == 0) {
return true; return true;
} }
$children = [];
$table_name = (new SysMenuModel)->getTable(); $table_name = (new SysMenuModel)->getTable();
$children = Db::query( if (env('DB_VERSION', '5') == '8') {
preg_replace( $children = Db::query(
'/\s+/u', preg_replace(
' ', '/\s+/u',
"WITH RECURSIVE menu_tree_by AS ( ' ',
SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']} "WITH RECURSIVE menu_tree_by AS (
UNION ALL SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$data['id']}
SELECT k.id, k.pid FROM $table_name k INNER JOIN menu_tree_by t ON t.id = k.pid UNION ALL
SELECT k.id, k.pid FROM $table_name k INNER JOIN menu_tree_by t ON t.id = k.pid
)
SELECT id FROM menu_tree_by WHERE id <> {$data['id']};"
) )
SELECT id FROM menu_tree_by WHERE id <> {$data['id']};" );
) } else {
); $children = \think\facade\Db::query("
SELECT t2.id
FROM (
SELECT
@r AS _id, (SELECT @r := GROUP_CONCAT(id) FROM $table_name WHERE FIND_IN_SET(pid, _id)) AS parent_id
FROM
(SELECT @r := {$data['id']}) vars, $table_name h
WHERE @r <> 0) t1
JOIN $table_name t2
ON FIND_IN_SET(t2.pid, t1._id)
ORDER BY t2.id;
");
}
if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) { if (!empty($children) && in_array($data['pid'], array_column($children, 'id'))) {
return false; return false;
} }

View File

@@ -274,17 +274,33 @@ class TopicNas extends Common
->value('id'); ->value('id');
// 获取帮且中心分类子分类 // 获取帮且中心分类子分类
$categorys = [];
$table_name = (new ArticleCategoryModel)->getTable(); $table_name = (new ArticleCategoryModel)->getTable();
$categorys = \think\facade\Db::query(preg_replace( if (env('DB_VERSION', '5') == '8') {
'/\s+/u', $categorys = \think\facade\Db::query(preg_replace(
' ', '/\s+/u',
"WITH RECURSIVE article_tree_by AS ( ' ',
SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$parent} "WITH RECURSIVE article_tree_by AS (
UNION ALL SELECT a.id, a.pid FROM $table_name a WHERE a.id = {$parent}
SELECT k.id, k.pid FROM $table_name k INNER JOIN article_tree_by t ON t.id = k.pid UNION ALL
) SELECT k.id, k.pid FROM $table_name k INNER JOIN article_tree_by t ON t.id = k.pid
SELECT id FROM article_tree_by WHERE id <> {$parent}" )
)); SELECT id FROM article_tree_by WHERE id <> {$parent}"
));
} else {
$categorys = \think\facade\Db::query("
SELECT t2.id
FROM (
SELECT
@r AS _id, (SELECT @r := GROUP_CONCAT(id) FROM $table_name WHERE FIND_IN_SET(pid, _id)) AS parent_id
FROM
(SELECT @r := $parent) vars, $table_name h
WHERE @r <> 0) t1
JOIN $table_name t2
ON FIND_IN_SET(t2.pid, t1._id)
ORDER BY t2.id;
");
}
if (empty($categorys)) return success('success', []); if (empty($categorys)) return success('success', []);
// 获取文章数据 // 获取文章数据