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

发布于 2024-09-18 05:41:06 字数 1529 浏览 9 评论 0原文

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

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]

如您所见,普通查询要快得多。有没有办法加快这个速度?

是否可以在 django 中使用 mysql 视图?

我意识到我可以将日期时间字段拆分为两个字段(日期和时间),但我很好奇。


结构:

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;

I use the following code to select popular news entries (by date) from the database:

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

To compare the execution speeds of a normal query and this one I ran the following mysql queries:

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]

As you can see the normal query is much faster. Is there a way to speed this up?

Is it possible to use mysql views with django?

I realize I could just split the datetime field into two fields (date and time), but I'm curious.


Structure:

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;

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

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

发布评论

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

评论(2

夏了南城 2024-09-25 05:41:06
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 上订购。

由于id很可能是表的PRIMARY KEY,并且每个PRIMARY KEY都有一个隐式索引支持它,ORDER BY< /code> 不需要排序。

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

此查询执行以下操作:

  • 选择第500记录dt_published DESC 顺序,或者如果表中的记录少于 500 则发布的第一条记录。

  • 获取晚于所选最后一条记录的日期发布的所有记录。由于 DATE(x) 始终小于或等于 x,因此可以有超过 500 记录,但仍然
    比整个表少得多。

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

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

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

This query orders on dpub, while this one:

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

orders on id.

Since id is most probably a PRIMARY KEY for your table, and each PRIMARY KEY has an implicit index backing it, ORDER BY does not need to sort.

dpub is a computed field and MySQL does not support indexes on computed fields. However, ORDER BY dt_published is an ORDER BY dpub as well.

You need to change your query to this:

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

and create an index on news_entry (dt_published).

Update:

Since DATE is a monotonic function, you may employ this trick:

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

This query does the following:

  • Selects the 500th record in dt_published DESC order, or the first record posted should there be less than 500 records in the table.

  • Fetches all records posted later than the date of the last record selected. Since DATE(x) is always less or equal to x, there can be more than 500 records, but still
    much less than the whole table.

  • Orders and limits these records as appropriate.

You may find this article interesting, since it covers a similar problem:

卖梦商人 2024-09-25 05:41:06

可能需要 dt_published 上的索引。您能发布这两个查询的查询计划吗?

May need an index on dt_published. Could you post the query plans for the two queries?

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