为 MYSQL 创建最近 30 天的视图

发布于 2024-09-04 10:48:53 字数 456 浏览 2 评论 0原文

我知道我写的查询是错误的,当我们获得大量流量时,我们的数据库会受到严重打击,页面速度会变慢...... 我想我需要根据 CURDATE 过去 30 天的 CREATE VIEW 编写查询?但不确定从哪里开始,或者这是否会是更有效的数据库查询?

无论如何,这是我编写的示例查询..

$query_Recordset6 = "SELECT `date`, title, category, url, comments 
                       FROM cute_news 
                      WHERE category LIKE '%45%' 
                   ORDER BY `date` DESC";

任何帮助或建议都会很棒!我有大约 11 个这样的查询,但我相信如果我能在其中一个查询上获得帮助,那么我就可以将它们实施到其余的查询中!

I know i am writing query's wrong and when we get a lot of traffic, our database gets hit HARD and the page slows to a grind...
I think I need to write queries based on CREATE VIEW from the last 30 days from the CURDATE ?? But not sure where to begin or if this will be MORE efficient query for the database?

Anyways, here is a sample query I have written..

$query_Recordset6 = "SELECT `date`, title, category, url, comments 
                       FROM cute_news 
                      WHERE category LIKE '%45%' 
                   ORDER BY `date` DESC";

Any help or suggestions would be great! I have about 11 queries like this, but I am confident if I could get help on one of these, then I can implement them to the rest!!

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

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

发布评论

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

评论(7

╰◇生如夏花灿烂 2024-09-11 10:48:53

在值比较的左侧放置通配符:

LIKE '%xyz'

...意味着无法使用索引,即使索引存在。可能需要考虑使用全文搜索 (FTS),这意味着添加全文索引

标准化数据将是另一个需要考虑的步骤 - 类别可能应该位于单独的表中。

Putting a wildcard on the left side of a value comparison:

LIKE '%xyz'

...means that an index can not be used, even if one exists. Might want to consider using Full Text Searching (FTS), which means adding full text indexing.

Normalizing the data would be another step to consider - categories should likely be in a separate table.

妳是的陽光 2024-09-11 10:48:53
SELECT `date`, title, category, url, comments 
                       FROM cute_news 
                      WHERE category LIKE '%45%' 
                   ORDER BY `date` DESC

LIKE '%45%' 表示需要执行全表扫描。您是否可能在该列中存储类别列表?如果是这样,创建一个存储类别和 news_article_id 的新表将允许使用索引更有效地检索匹配记录。

SELECT `date`, title, category, url, comments 
                       FROM cute_news 
                      WHERE category LIKE '%45%' 
                   ORDER BY `date` DESC

The LIKE '%45%' means a full table scan will need to be performed. Are you perhaps storing a list of categories in the column? If so creating a new table storing category and news_article_id will allow an index to be used to retrieve the matching records much more efficiently.

另类 2024-09-11 10:48:53

好的,是时候进行心理调试了。

在我看来,我发现通过数据库规范化,查询性能将得到显着提高,特别是通过将类别多值列拆分为一个具有两列的单独表:cute_news 的主键和类别 ID。

这还允许您直接将所述表链接到类别表,而无需先解析它。

或者,正如 Chris Date 所说:“每个行和列的交集都包含来自适用域的一个值(而不是其他值)。”

OK, time for psychic debugging.

In my mind's eye, I see that query performance would be improved considerably through database normalization, specifically by splitting the category multi-valued column into a a separate table that has two columns: the primary key for cute_news and the category ID.

This would also allow you to directly link said table to the categories table without having to parse it first.

Or, as Chris Date said: "Every row-and-column intersection contains exactly one value from the applicable domain (and nothing else)."

蘸点软妹酱 2024-09-11 10:48:53

任何带有 LIKE '%XXX%' 的东西都会很慢。这是一个缓慢的操作。

对于类别之类的内容,您可能希望将类别分离到另一个表中,并在cute_news 表中使用外键。这样你就可以拥有category_id,并在查询中使用它,这样会快得多。


另外,我不太清楚你为什么要谈论使用 CREATE VIEW。视图并不能真正帮助你提高速度。除非它是物化视图,而 MySQL 本身并不认为它是物化视图。

Anything with LIKE '%XXX%' is going to be slow. Its a slow operation.

For something like categories, you might want to separate categories out into another table and use a foreign key in the cute_news table. That way you can have category_id, and use that in the query which will be MUCH faster.


Also, I'm not quite sure why you're talking about using CREATE VIEW. Views will not really help you for speed. Not unless its a materialized view, which MySQL doesn't suppose natively.

花心好男孩 2024-09-11 10:48:53

如果您的数据库受到严重打击,解决方案不是创建视图(视图仍然基本上与数据库要做的工作量相同),解决方案是缓存结果。

这一点特别适用,因为听起来您的数据只需每 30 天刷新一次。

If your database is getting hit hard, the solution isn't to make a view (the view is still basically the same amount of work for the database to do), the solution is to cache the results.

This is especially applicable since, from what it sounds like, your data only needs to be refreshed once every 30 days.

流云如水 2024-09-11 10:48:53

我猜您的 category 列是一个类别值列表,例如“12,34,45,78”?

这不是好的关系数据库设计。正如您所发现的,它不好的原因之一是:搜索可能出现在该列表中间的子字符串非常慢。

有些人建议使用全文搜索而不是带有通配符的 LIKE 谓词,但在这种情况下,创建另一个表会更简单,这样您就可以每行列出一个类别值,并引用回您的 cute_news 表:

CREATE TABLE cute_news_category (
  news_id INT NOT NULL,
  category INT NOT NULL,
  PRIMARY KEY (news_id, category),
  FOREIGN KEY (news_id) REFERENCES cute_news(news_id)
) ENGINE=InnoDB;

然后你就可以查询了,速度会快很多:

SELECT n.`date`, n.title, c.category, n.url, n.comments 
FROM cute_news n
JOIN cute_news_category c ON (n.news_id = c.news_id)
WHERE c.category = 45 
ORDER BY n.`date` DESC

I'd guess that your category column is a list of category values like "12,34,45,78" ?

This is not good relational database design. One reason it's not good is as you've discovered: it's incredibly slow to search for a substring that might appear in the middle of that list.

Some people have suggested using fulltext search instead of the LIKE predicate with wildcards, but in this case it's simpler to create another table so you can list one category value per row, with a reference back to your cute_news table:

CREATE TABLE cute_news_category (
  news_id INT NOT NULL,
  category INT NOT NULL,
  PRIMARY KEY (news_id, category),
  FOREIGN KEY (news_id) REFERENCES cute_news(news_id)
) ENGINE=InnoDB;

Then you can query and it'll go a lot faster:

SELECT n.`date`, n.title, c.category, n.url, n.comments 
FROM cute_news n
JOIN cute_news_category c ON (n.news_id = c.news_id)
WHERE c.category = 45 
ORDER BY n.`date` DESC
囍笑 2024-09-11 10:48:53

任何答案都是猜测,请显示:
- 相关的 SHOW CREATE TABLE 输出
- 常见查询的 EXPLAIN 输出。

比尔·卡尔文的评论当然适用。

毕竟这&优化,仍然需要将数据采样到仅包含最近 30 天的表中,在这种情况下,您最好运行每日 cronjob 来做到这一点。

Any answer is a guess, show:
- the relevant SHOW CREATE TABLE outputs
- the EXPLAIN output from your common queries.

And Bill Karwin's comment certainly applies.

After all this & optimizing, sampling the data into a table with only the last 30 days could still be desired, in which case you're better of running a daily cronjob to do just that.

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