对 Sphinx 的 SQL 查询的现实检查
Reality check on a SQL query for Sphinx
我正在努力实现 Sphinx 作为我网站的搜索服务器。该网站允许教师建立评估项目——我正在寻找索引——可以包括:
- 一个上下文(每个项目一个)
- 一个或多个问题(每个项目很多)
- 每个问题的答案(每个问题很多)
- 每个问题的类别(多对多)
我对 Sphinx 和直接使用 MySQL 都是新手,因为我的其他搜索是通过 CakePHP 的函数进行的。
在构建一个可以索引数据库中的问题的视图时,我提出了以下 SQL 查询(它很大,但我不会要求您调试它):
SELECT
questions.id,
CONCAT(
IFNULL(questions.context_template, ''),
IFNULL(context_answers_concat.context_answer_templates, ''),
IFNULL(parts_concat.full_parts, '')
) as full_question,
parts_concat.all_categories
FROM
questions
LEFT JOIN(
SELECT
question_answers.question_id,
GROUP_CONCAT(
question_answers.answer_template
) AS context_answer_templates
FROM
question_answers
GROUP BY
question_answers.question_id
) AS context_answers_concat
ON
context_answers_concat.question_id = questions.id
LEFT JOIN(
SELECT
question_parts.question_id,
GROUP_CONCAT(
CONCAT(
question_parts.question_template,
IFNULL(answers_concat.answer_templates, '')
)
) AS full_parts,
GROUP_CONCAT(
categories_concat.part_categories
) AS all_categories
FROM
question_parts
LEFT JOIN(
SELECT
question_answers.question_part_id,
GROUP_CONCAT(
question_answers.answer_template
) AS answer_templates
FROM
question_answers
GROUP BY
question_answers.question_part_id
) AS answers_concat
ON
answers_concat.question_part_id = question_parts.id
LEFT JOIN(
SELECT
question_categories.question_part_id,
GROUP_CONCAT(DISTINCT categories.type) AS part_categories
FROM
question_categories,
categories
WHERE
question_categories.category_id = categories.id
GROUP BY
question_categories.question_part_id
) AS categories_concat
ON
categories_concat.question_part_id = question_parts.id
GROUP BY
question_parts.question_id
) AS parts_concat
ON
parts_concat.question_id = questions.id
我在 phpMyAdmin 中 运行 查询,它生成了我期望的视图 -- 一个 id 列,一个包含问题和答案文本的列,以及一个类别列。
我的问题是,因为它太大了,用于在 Sphinx 中索引类似的东西是否是一个合理的查询?如果不是,我应该使用 Sphinx 的其他部分来完成这项工作吗?或者不同的 SQL 功能?
只要您熟悉查询的性能和查询 returns 您所需要的,我看不出有任何问题。我看到查询更大,Sphinx / Manticore 与它们配合得很好。
或者,您可以使用 real-time 索引,在这种情况下,您需要将数据插入索引,而不是使用索引器从 mysql 中获取数据。
如果您想坚持使用普通索引并使用索引器,请考虑一下我还建议您考虑将索引拆分为主要部分和增量部分,以便您可以更频繁地重建增量部分。除非您的索引很小并且重建所需的时间微不足道,否则您无需担心。
我正在努力实现 Sphinx 作为我网站的搜索服务器。该网站允许教师建立评估项目——我正在寻找索引——可以包括:
- 一个上下文(每个项目一个)
- 一个或多个问题(每个项目很多)
- 每个问题的答案(每个问题很多)
- 每个问题的类别(多对多)
我对 Sphinx 和直接使用 MySQL 都是新手,因为我的其他搜索是通过 CakePHP 的函数进行的。
在构建一个可以索引数据库中的问题的视图时,我提出了以下 SQL 查询(它很大,但我不会要求您调试它):
SELECT
questions.id,
CONCAT(
IFNULL(questions.context_template, ''),
IFNULL(context_answers_concat.context_answer_templates, ''),
IFNULL(parts_concat.full_parts, '')
) as full_question,
parts_concat.all_categories
FROM
questions
LEFT JOIN(
SELECT
question_answers.question_id,
GROUP_CONCAT(
question_answers.answer_template
) AS context_answer_templates
FROM
question_answers
GROUP BY
question_answers.question_id
) AS context_answers_concat
ON
context_answers_concat.question_id = questions.id
LEFT JOIN(
SELECT
question_parts.question_id,
GROUP_CONCAT(
CONCAT(
question_parts.question_template,
IFNULL(answers_concat.answer_templates, '')
)
) AS full_parts,
GROUP_CONCAT(
categories_concat.part_categories
) AS all_categories
FROM
question_parts
LEFT JOIN(
SELECT
question_answers.question_part_id,
GROUP_CONCAT(
question_answers.answer_template
) AS answer_templates
FROM
question_answers
GROUP BY
question_answers.question_part_id
) AS answers_concat
ON
answers_concat.question_part_id = question_parts.id
LEFT JOIN(
SELECT
question_categories.question_part_id,
GROUP_CONCAT(DISTINCT categories.type) AS part_categories
FROM
question_categories,
categories
WHERE
question_categories.category_id = categories.id
GROUP BY
question_categories.question_part_id
) AS categories_concat
ON
categories_concat.question_part_id = question_parts.id
GROUP BY
question_parts.question_id
) AS parts_concat
ON
parts_concat.question_id = questions.id
我在 phpMyAdmin 中 运行 查询,它生成了我期望的视图 -- 一个 id 列,一个包含问题和答案文本的列,以及一个类别列。
我的问题是,因为它太大了,用于在 Sphinx 中索引类似的东西是否是一个合理的查询?如果不是,我应该使用 Sphinx 的其他部分来完成这项工作吗?或者不同的 SQL 功能?
只要您熟悉查询的性能和查询 returns 您所需要的,我看不出有任何问题。我看到查询更大,Sphinx / Manticore 与它们配合得很好。
或者,您可以使用 real-time 索引,在这种情况下,您需要将数据插入索引,而不是使用索引器从 mysql 中获取数据。
如果您想坚持使用普通索引并使用索引器,请考虑一下我还建议您考虑将索引拆分为主要部分和增量部分,以便您可以更频繁地重建增量部分。除非您的索引很小并且重建所需的时间微不足道,否则您无需担心。