重写查询以删除 FIND_IN_SET?

发布于 2024-09-05 00:50:33 字数 559 浏览 0 评论 0原文

我的 mysql 查询如下所示:

    SELECT pages.*,
           showcase.*,
           project.*    
      FROM pages
INNER JOIN showcase ON showcase.pid = pages.uid AND showcase.deleted != 1
INNER JOIN project ON FIND_IN_SET(project.uid, showcase.projects)   
     WHERE pages.deleted != 1
       AND pages.pid = 14
       AND pages.dokType = 150

问题是第二个 INNER JOIN - 它使用 FIND_IN_SET 因为展示(=项目集合)将其项目存储为逗号分隔列表字段showcase.projects。据我所知,FIND_IN_SET 无法使用索引,因此第二次连接需要对项目表进行全表扫描。是否有可能在不更改数据库方案的情况下使用索引?

My mysql query looks like this:

    SELECT pages.*,
           showcase.*,
           project.*    
      FROM pages
INNER JOIN showcase ON showcase.pid = pages.uid AND showcase.deleted != 1
INNER JOIN project ON FIND_IN_SET(project.uid, showcase.projects)   
     WHERE pages.deleted != 1
       AND pages.pid = 14
       AND pages.dokType = 150

The problem is the second INNER JOIN - it uses FIND_IN_SET because a showcase (= collection of projects) stores its projects as a comma separated list in the field showcase.projects. FIND_IN_SET cant use indexes as far as I know, so the second join requires a full table scan of the project table. Any possibility to use an index without changing the database scheme?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

灵芸 2024-09-12 00:50:33

您在另一个字符串中搜索“字符串”。无论如何,你都必须进行扫描。使用索引执行此操作的另一种优化方法是使用连接表。创建一个新表 showcase_projects,其中包含 project_idshowcase_id 列。然后,这将记录两者之间的每个关联。

现在这个答案是基于我对这个查询的数据结构的原始理解。

You searching for a 'string' inside another string. You'll have to do a scan regardless. The other optimized way to do this using indexes is to use a join table. Create a new table showcase_projects that has columns of project_id and showcase_id. This will then have a record for every association between the two.

Now this answer is based on my primitive understanding of your datastructure from this query.

紫轩蝶泪 2024-09-12 00:50:33

showcase.projectsVARCHAR 吗?然后你可以像这样使用 REGEXP

...
INNER JOIN project ON
showcase.projects REGEXP CONCAT('[[:<:]]', project.uid, '[[:>:]]')
WHERE ...

这个表达式仅查找整个单词(括号结构分别标记左右单词边界。但是,我不确定这是否能够利用一个索引,也许有人可以想出更聪明的东西。

Is showcase.projects a VARCHAR? Then you could use REGEXP like this:

...
INNER JOIN project ON
showcase.projects REGEXP CONCAT('[[:<:]]', project.uid, '[[:>:]]')
WHERE ...

This expression looks for whole words only (the bracket constructions mark left and right word boundaries, respectively. However, I'm not sure this will be able to make use of an index, maybe someone can come up with something smarter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文