【问题标题】:CREATE VIEW for MYSQL for last 30 days过去 30 天为 MYSQL 创建视图
【发布时间】:2010-06-04 18:41:02
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: php mysql query-optimization


    【解决方案1】:

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

    LIKE '%xyz'
    

    ...表示不能使用索引,即使存在索引。可能要考虑使用Full Text Searching (FTS), which means adding full text indexing

    规范化数据将是另一个需要考虑的步骤 - 类别可能应该在单独的表中。

    【讨论】:

    • 想知道这是否会更好?选择...从...限制 50
    【解决方案2】:
    SELECT `date`, title, category, url, comments 
                           FROM cute_news 
                          WHERE category LIKE '%45%' 
                       ORDER BY `date` DESC
    

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

    【讨论】:

      【解决方案3】:

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

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

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

      或者,正如 Chris Date 所说:“每个行列交集都只包含来自适用域的一个值(仅此而已)。”

      【讨论】:

        【解决方案4】:

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

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


        另外,我不太清楚您为什么要使用 CREATE VIEW。视图不会真正帮助您提高速度。除非它是物化视图,否则 MySQL 不认为它是本机的。

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

            我猜您的 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
            

            【讨论】:

              【解决方案7】:

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

              Bill Karwin 的评论当然适用。

              在所有这些和优化之后,仍然需要将仅包含过去 30 天的数据抽样到一个表中,在这种情况下,您最好运行一个每日 cronjob 来做到这一点。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-07-27
                • 1970-01-01
                • 2012-12-09
                • 2020-09-28
                • 2011-01-03
                • 1970-01-01
                • 1970-01-01
                • 2019-07-18
                相关资源
                最近更新 更多