代码之家  ›  专栏  ›  技术社区  ›  demux

在django中加速mysql查询/mysql视图

  •  1
  • demux  · 技术社区  · 14 年前

    我使用以下代码从数据库中选择热门新闻条目(按日期):

    popular = Entry.objects.filter(type='A', is_public=True).extra(select = {'dpub': 'date(dt_published)'}).order_by('-dpub', '-views', '-dt_written', 'headline')[0:5]
    

    为了比较普通查询和此查询的执行速度,我运行了以下mysql查询:

    SELECT *, date(dt_published) as dpub FROM `news_entry` order by dpub DESC LIMIT 500
    
    # Showing rows 0 - 29 (500 total, Query took 0.1386 sec)
    

    SELECT * , DATE( dt_published ) AS dpub FROM  `news_entry` ORDER BY id DESC LIMIT 500
    
    # Showing rows 0 - 29 (500 total, Query took 0.0021 sec) [id: 58079 - 57580]
    

    正如您所看到的,普通查询要快得多。有没有办法加快速度?

    是否可以将mysql视图与django一起使用?

    我知道我可以把datetime字段分成两个字段(日期和时间),但我很好奇。


    结构:

    CREATE TABLE IF NOT EXISTS `news_entry` (
      `id` int(11) NOT NULL DEFAULT '0',
      `views` int(11) NOT NULL,
      `user_views` int(11) NOT NULL,
      `old_id` int(11) DEFAULT NULL,
      `type` varchar(1) NOT NULL,
      `headline` varchar(256) NOT NULL,
      `subheadline` varchar(256) NOT NULL,
      `slug` varchar(50) NOT NULL,
      `category_id` int(11) DEFAULT NULL,
      `is_public` tinyint(1) NOT NULL,
      `is_featured` tinyint(1) NOT NULL,
      `dt_written` datetime DEFAULT NULL,
      `dt_modified` datetime DEFAULT NULL,
      `dt_published` datetime DEFAULT NULL,
      `author_id` int(11) DEFAULT NULL,
      `author_alt` varchar(256) NOT NULL,
      `email_alt` varchar(256) NOT NULL,
      `tags` varchar(255) NOT NULL,
      `content` longtext NOT NULL
    ) ENGINE=MyISAM DEFAULT;
    
    2 回复  |  直到 14 年前
        1
  •  2
  •   Quassnoi    14 年前
    SELECT *, date(dt_published) as dpub FROM `news_entry` order by dpub DESC LIMIT 500
    

    此查询在 dpub ,而这个:

    SELECT * , DATE( dt_published ) AS dpub FROM  `news_entry` ORDER BY id DESC LIMIT 500
    

    订单 id .

    PRIMARY KEY 为您的桌子,和每个 主键 有一个隐式索引支持它, ORDER BY 不需要排序。

    dpub公司 是一个计算字段 MySQL 不支持计算字段上的索引。然而, ORDER BY dt_published 是一个 ORDER BY dpub 也。

    您需要将查询更改为:

    SELECT *, date(dt_published) as dpub FROM `news_entry` order by date_published DESC LIMIT 500
    

    并在上创建索引 news_entry (dt_published) .

    更新:

    DATE 是一个单调函数,你可以使用这个技巧:

    SELECT  *, DATE(dt_published) AS dpub
    FROM    news_entry
    WHERE   dt_published >=
            (
            SELECT  md
            FROM    (
                    SELECT  DATE(dt_published) AS md
                    FROM    news_entry
                    ORDER BY
                            dt_published DESC
                    LIMIT 499, 1
                    ) q
            UNION ALL
            SELECT  DATE(MIN(dt_published))
            FROM    news_entry
            LIMIT 1
            )
    ORDER BY
            dpub DESC, views DESC, dt_written DESC, headline
    LIMIT 500
    

    • 选择 500th dt_published DESC 订单或发布的第一条记录应少于 500

    • 日期 DATE(x) 总是小于或等于 x ,可以有超过 500

    • 适当的命令和限制这些记录。

    您可能会发现这篇文章很有趣,因为它涵盖了一个类似的问题:

        2
  •  0
  •   zevra0    14 年前

    dt_published . 你能把这两个查询的查询计划贴出来吗?