1

次のコードを使用して、データベースから人気のあるニュース エントリを (日付別に) 選択します。

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 ビューを使用することは可能ですか?

datetime フィールドを 2 つのフィールド (日付と時刻) に分割できることはわかっていますが、興味があります。


構造:

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;
4

2 に答える 2

2
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があり、ソートする必要はありません。

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、テーブル全体よりもはるかに少ない場合があります。

  • 必要に応じて、これらのレコードを並べ替えて制限します。

同様の問題をカバーしているため、この記事は興味深いかもしれません。

于 2010-09-07T13:06:31.970 に答える
0

の索引が必要な場合がありますdt_published。2 つのクエリのクエリ プランを投稿していただけますか?

于 2010-09-07T13:07:11.160 に答える