أقوم بتشغيل الاختبارات في Discourse وأجد بعض الاستعلامات غير الفعّالة في سجل الاستعلامات على النحو التالي:
- استخدام DISTINCT غير ضروري يبطئ الاستعلام site_settings_controller.rb#L165 كما يلي:
SELECT
DISTINCT users.id
FROM
"users" CROSS
JOIN categories c
LEFT JOIN category_users cu ON users.id = cu.user_id
AND c.id = cu.category_id
WHERE
(
c.id = '3613'
AND cu.notification_level IS NULL
)
عند تحديد قيم لـ categories.id و notification_level، وبسبب وجود UNIQUE (category_id, user_id) في جدول category_users و PRIMARY KEY(id) في جدول categories، فإن كل من عمليات الربط المتقاطع (cross join) والربط الأيسر (left join) لن تُنتج سجلات مكررة، مما يعني أنه يمكننا إزالة DISTINCT لتسريع الاستعلام كما هو موضح أدناه:
استغرق الاستعلام المحسّن 4532166 نانوثانية (تحسين بنسبة 30%)
- استخدام DISTINCT غير ضروري في الاستعلام الفرعي يبطئ الاستعلام search.rb#L523
SELECT
"posts".*
FROM
"posts"
JOIN (
SELECT
*,
row_number() over() row_number
FROM
(
SELECT
topics.id,
min(posts.post_number) post_number
FROM
"posts"
INNER JOIN "post_search_data" ON "post_search_data"."post_id" = "posts"."id"
INNER JOIN "topics" ON "topics"."id" = "posts"."topic_id"
AND ("topics"."deleted_at" IS NULL)
LEFT JOIN categories ON categories.id = topics.category_id
WHERE
("posts"."deleted_at" IS NULL)
AND "posts"."post_type" IN (1, 2, 3)
AND (topics.visible)
AND (
topics.archetype <> 'private_message'
)
AND (
topics.id IN (
SELECT
DISTINCT(tt.topic_id)
FROM
topic_tags tt
WHERE
tt.tag_id in (
SELECT
tag_id
FROM
tag_group_memberships
WHERE
tag_group_id = 504
)
)
)
AND (
categories.id NOT IN (
SELECT
categories.id
WHERE
categories.search_priority = 1
)
)
AND (
(categories.id IS NULL)
OR (NOT categories.read_restricted)
)
GROUP BY
topics.id
ORDER BY
MAX(posts.created_at) DESC
LIMIT
6 OFFSET 0
) xxx
) x ON x.id = posts.topic_id
AND x.post_number = posts.post_number
WHERE
("posts"."deleted_at" IS NULL)
ORDER BY
row_number
استخدام DISTINCT(tt.topic_id) زائد عن الحاجة ويمكن إزالته لتسريع الاستعلام كما هو موضح أدناه:
يمكن أن يحسّن أداء هذا الاستعلام من 12655768 إلى 5005154 (تحسين بنسبة 60%)
- استخدام DISTINCT غير ضروري في الاستعلام الفرعي يبطئ الاستعلام [search.rb#L642]
SELECT
"posts".*
FROM
"posts"
JOIN (
SELECT
*,
row_number() over() row_number
FROM
(
SELECT
topics.id,
posts.post_number
FROM
"posts"
INNER JOIN "post_search_data" ON "post_search_data"."post_id" = "posts"."id"
INNER JOIN "topics" ON "topics"."id" = "posts"."topic_id"
AND ("topics"."deleted_at" IS NULL)
LEFT JOIN categories ON categories.id = topics.category_id
WHERE
("posts"."deleted_at" IS NULL)
AND "posts"."post_type" IN (1, 2, 3)
AND (topics.visible)
AND (
topics.archetype <> 'private_message'
)
AND (
topics.category_id IN (3715)
)
AND (
topics.id IN (
SELECT
DISTINCT(tt.topic_id)
FROM
topic_tags tt,
tags
WHERE
tt.tag_id = tags.id
AND lower(tags.name) IN ('lunch')
)
)
AND (
(categories.id IS NULL)
OR (NOT categories.read_restricted)
)
ORDER BY
posts.like_count DESC
LIMIT
6 OFFSET 0
) xxx
) x ON x.id = posts.topic_id
AND x.post_number = posts.post_number
WHERE
("posts"."deleted_at" IS NULL)
ORDER BY
row_number
مشابه للسابق (مع اختلاف في كود المصدر)، فإن استخدام DISTINCT(tt.topic_id) زائد عن الحاجة ويمكن إزالته لتسريع الاستعلام:
يمكن أن يحسّن أداء هذا الاستعلام من 23659762 إلى 21030593 (تحسين بنسبة 10%).