如何让这个查询运行得更快?

发布于 2024-12-17 12:09:33 字数 2505 浏览 2 评论 0原文

我有这样的查询:

    SELECT 
    `om_chapter`.`manganame` as `link`,
    (SELECT `manganame` FROM `om_manga` WHERE `Active` = '1' AND `om_manga`.`link` = `om_chapter`.`manganame` LIMIT 0,1) AS `manganame`,
    (SELECT `cover` FROM `om_manga` WHERE `Active` = '1' AND `om_manga`.`link` = `om_chapter`.`manganame` LIMIT 0,1) AS `cover`,
    (SELECT `othername` FROM `om_manga` WHERE `Active` = '1' AND `om_manga`.`link` = `om_chapter`.`manganame` LIMIT 0,1) AS `othername`
FROM `om_chapter`
WHERE 
    `Active` = '1' AND 
    (SELECT `Active` From `om_manga` WHERE `om_manga`.`link` = `om_chapter`.`manganame` LIMIT 0,1) AND 
    `id` IN ( SELECT MAX(`id`) FROM `om_chapter` WHERE `Active` = '1' GROUP BY `manganame` )
ORDER BY `id` DESC LIMIT 10

那么我怎样才能使这个查询更快呢?

这是我的表格:

om_chapter:

id  | manganame     | chapter   | Active
-----------------------------------------
1   | naruto        | 1         | 1
2   | naruto        | 12        | 1
3   | naruto        | 22        | 1
4   | bleach        | 10        | 1
5   | bleach        | 15        | 1
6   | gents         | 1         | 1
7   | naruto        | 21        | 1

om_manga:

id  | othername | manganame     | cover     | Active
-----------------------------------------------------
1   | naruto    | naruto        | n.jpg     | 1
2   | bleach    | bleach        | b.jpg     | 1
4   | gents     | gents         | g.jpg     | 1 

我想要形成这个查询的第一件事是通过对 manganame 进行分组并按 id 排序,为我提供 om_chapter 的最后 10 行。我尝试通过使用组甚至不同的方式来使用简单的查询,但没有他们给了我正确的结果...

在带有组或不同的简单查询中,结果是这样的:

id  | manganame     | chapter   | Active
-----------------------------------------
7   | prince        | 21        | 1
5   | gent          | 15        | 1
2   | naruto        | 12        | 1
1   | bleach        | 1         | 1

但我想要这个结果:

id  | manganame     | chapter   | Active
-----------------------------------------
9   | gents         | 21        | 1
8   | bleach        | 21        | 1
7   | prince        | 21        | 1
6   | naruto        | 1         | 1

所以我使用这个:

WHERE 
`Active` = '1' AND 
(SELECT `Active` From `om_manga` WHERE `om_manga`.`link` = `om_chapter`.`manganame` LIMIT 0,1) AND 
`id` IN ( SELECT MAX(`id`) FROM `om_chapter` WHERE `Active` = '1' GROUP BY `manganame` )

并且我在其中使用子选择,因为我想要 Active 的om_manga表中的字段为1..

对于子选择的重置,我实际上没有尝试加入,但我会..!

I have query like this:

    SELECT 
    `om_chapter`.`manganame` as `link`,
    (SELECT `manganame` FROM `om_manga` WHERE `Active` = '1' AND `om_manga`.`link` = `om_chapter`.`manganame` LIMIT 0,1) AS `manganame`,
    (SELECT `cover` FROM `om_manga` WHERE `Active` = '1' AND `om_manga`.`link` = `om_chapter`.`manganame` LIMIT 0,1) AS `cover`,
    (SELECT `othername` FROM `om_manga` WHERE `Active` = '1' AND `om_manga`.`link` = `om_chapter`.`manganame` LIMIT 0,1) AS `othername`
FROM `om_chapter`
WHERE 
    `Active` = '1' AND 
    (SELECT `Active` From `om_manga` WHERE `om_manga`.`link` = `om_chapter`.`manganame` LIMIT 0,1) AND 
    `id` IN ( SELECT MAX(`id`) FROM `om_chapter` WHERE `Active` = '1' GROUP BY `manganame` )
ORDER BY `id` DESC LIMIT 10

So how can I make this query faster?

Here are my tables:

om_chapter:

id  | manganame     | chapter   | Active
-----------------------------------------
1   | naruto        | 1         | 1
2   | naruto        | 12        | 1
3   | naruto        | 22        | 1
4   | bleach        | 10        | 1
5   | bleach        | 15        | 1
6   | gents         | 1         | 1
7   | naruto        | 21        | 1

om_manga:

id  | othername | manganame     | cover     | Active
-----------------------------------------------------
1   | naruto    | naruto        | n.jpg     | 1
2   | bleach    | bleach        | b.jpg     | 1
4   | gents     | gents         | g.jpg     | 1 

First thing i want form this query is to give me 10 last rows form om_chapter by grouping manganame and ordering by id.. i try to use a simple query by using group or even distinct but none of them give me the right result...

In a simple query with group or distinct, the result is like this:

id  | manganame     | chapter   | Active
-----------------------------------------
7   | prince        | 21        | 1
5   | gent          | 15        | 1
2   | naruto        | 12        | 1
1   | bleach        | 1         | 1

But i want this result:

id  | manganame     | chapter   | Active
-----------------------------------------
9   | gents         | 21        | 1
8   | bleach        | 21        | 1
7   | prince        | 21        | 1
6   | naruto        | 1         | 1

So i use this:

WHERE 
`Active` = '1' AND 
(SELECT `Active` From `om_manga` WHERE `om_manga`.`link` = `om_chapter`.`manganame` LIMIT 0,1) AND 
`id` IN ( SELECT MAX(`id`) FROM `om_chapter` WHERE `Active` = '1' GROUP BY `manganame` )

And i use sub select in where because i want Active's field in om_manga's table be 1..

For the reset of sub select, i actually didn`t try join, but i will..!

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

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

发布评论

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

评论(4

书间行客 2024-12-24 12:09:33

我可能误解了你的意图..但这里有一个尝试:

SELECT c.`manganame` AS `link`
     , m.`manganame`
     , m.`cover`
     , m.`othername`
FROM 
     `om_manga` m 
     INNER JOIN `om_chapter` c 
     ON m.`link` = c.`manganame`
     INNER JOIN 
     ( SELECT `manganame`, MAX(`id`) AS `maxid` 
       FROM `om_chapter` 
       WHERE `Active` = '1' 
       GROUP BY `manganame` ) mx
     ON mx.`maxid` = c.`id`
ORDER BY c.`id` DESC LIMIT 10

I might have misunderstood your intentions.. But here's one try:

SELECT c.`manganame` AS `link`
     , m.`manganame`
     , m.`cover`
     , m.`othername`
FROM 
     `om_manga` m 
     INNER JOIN `om_chapter` c 
     ON m.`link` = c.`manganame`
     INNER JOIN 
     ( SELECT `manganame`, MAX(`id`) AS `maxid` 
       FROM `om_chapter` 
       WHERE `Active` = '1' 
       GROUP BY `manganame` ) mx
     ON mx.`maxid` = c.`id`
ORDER BY c.`id` DESC LIMIT 10
世态炎凉 2024-12-24 12:09:33

我将向 om_chapter 表引入一个外键约束,以说明从漫画到其相应章节的链接。

这就是我如何概念化这个问题。

A manga can have many chapters.  A chapter belongs to one manga. 

然后我会更改 om_chapter 表,以包含链接到漫画的章节的外键。

ALTER TABLE om_Chapter (
ADD mangaID int references om_Manga (id)
)

并删除 manganame 列,因为它现在是多余的,

 ALTER TABLE om_Chapter (
 DROP COLUMN manganame
)

然后您的表可能如下所示。

om_manga:

id  | othername | manganame     | cover     | Active
-----------------------------------------------------
1   | naruto    | naruto        | n.jpg     | 1
2   | bleach    | bleach        | b.jpg     | 1
4   | gents     | gents         | g.jpg     | 1 

om_chapter:

id  | chapter   | Active  | mangaID
-----------------------------------------
1   | 1         | 1       |  1
2   | 12        | 1       |  1
3   | 22        | 1       |  1
4   | 10        | 1       |  2
5   | 15        | 1       |  2
6   | 1         | 1       |  4

最后你可以像这样查询表

SELECT TOP 10 m.Manganame as link,
  m.Manganame,
  m.cover,
  m.othername,

FROM om_manga as m INNER JOIN
  om_chapter as c ON m.ID = c.mangaID

WHERE m.active = 1 AND c.active = 1
ORDER BY m.ID DESC

I would introduce a foreign key contstrain to the om_chapter table to account for the link from a manga to its corresponding chapters.

This is how I would conceptualize the problem.

A manga can have many chapters.  A chapter belongs to one manga. 

Then I would alter the om_chapter table, to include a foreign key for the chapter to link to the manga.

ALTER TABLE om_Chapter (
ADD mangaID int references om_Manga (id)
)

And drop the manganame column as it is just redundant now

 ALTER TABLE om_Chapter (
 DROP COLUMN manganame
)

Your tables then could look like this.

om_manga:

id  | othername | manganame     | cover     | Active
-----------------------------------------------------
1   | naruto    | naruto        | n.jpg     | 1
2   | bleach    | bleach        | b.jpg     | 1
4   | gents     | gents         | g.jpg     | 1 

om_chapter:

id  | chapter   | Active  | mangaID
-----------------------------------------
1   | 1         | 1       |  1
2   | 12        | 1       |  1
3   | 22        | 1       |  1
4   | 10        | 1       |  2
5   | 15        | 1       |  2
6   | 1         | 1       |  4

Finally you could query the tables like so

SELECT TOP 10 m.Manganame as link,
  m.Manganame,
  m.cover,
  m.othername,

FROM om_manga as m INNER JOIN
  om_chapter as c ON m.ID = c.mangaID

WHERE m.active = 1 AND c.active = 1
ORDER BY m.ID DESC
话少心凉 2024-12-24 12:09:33

为什么不简单的加入呢?

SELECT om_chapter.manganame, cover, othername
FROM om_chapter
JOIN om_manga ON om_chapter.manganame = om_manga=manganame
WHERE om_chapter.Active = 1 AND om_manga.Active = 1

除非我误读了你的版本。

Why not a simple join?

SELECT om_chapter.manganame, cover, othername
FROM om_chapter
JOIN om_manga ON om_chapter.manganame = om_manga=manganame
WHERE om_chapter.Active = 1 AND om_manga.Active = 1

unless I'm misreading your version.

你又不是我 2024-12-24 12:09:33

使用左外连接(并丢失子查询和反引号):

SELECT c.manganame AS link,
       m.manganame AS manganame,
       m.cover     AS cover,
       m.othername AS `othername
  FROM om_chapter    AS c
  LEFT JOIN om_manga AS m
    ON c.manganame = m.manganame
 WHERE c.Active = '1'
   AND c.id IN (SELECT MAX(o.id)
                  FROM om_chapter AS o
                 WHERE o.active = 1
                 GROUP BY o.manganame)
 ORDER BY c.id DESC LIMIT 10

如果是我的查询,我可能也会选择“c.id AS id”。

Use a left outer join (and lose the sub-queries, and the back-quotes):

SELECT c.manganame AS link,
       m.manganame AS manganame,
       m.cover     AS cover,
       m.othername AS `othername
  FROM om_chapter    AS c
  LEFT JOIN om_manga AS m
    ON c.manganame = m.manganame
 WHERE c.Active = '1'
   AND c.id IN (SELECT MAX(o.id)
                  FROM om_chapter AS o
                 WHERE o.active = 1
                 GROUP BY o.manganame)
 ORDER BY c.id DESC LIMIT 10

Were it my query, I'd probably select 'c.id AS id' too.

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