Domanda

Io uso il seguente codice per selezionare le voci di notizie popolari (per data) dal 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]

Per confrontare le velocità di esecuzione di una query normale e questo mi sono imbattuto le seguenti query 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]

Come si può vedere la query normale è molto più veloce. C'è un modo per accelerare questo?

E 'possibile utilizzare le visualizzazioni MySQL con Django?

Mi rendo conto che ho potuto solo dividere il campo datetime in due campi (data e ora), ma sono curioso.


Struttura:

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;
È stato utile?

Soluzione

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

Nella query Ordini dpub, mentre questo:

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

ordini su id.

Dal id è più probabilmente un PRIMARY KEY per la vostra tavola, e ciascuno PRIMARY KEY ha un indice implicito sostenerla, ORDER BY non ha bisogno di sorta.

dpub è un campo calcolato e MySQL non supporta gli indici sui campi calcolati. Tuttavia, è un ORDER BY dt_published ORDER BY dpub pure.

È necessario modificare la tua ricerca a questo:

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

e creare un indice su news_entry (dt_published).

Aggiornamento:

Dato DATE è una funzione monotona, si può impiegare questo trucco:

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

Questa query fa il seguente:

  • seleziona il record 500th al fine dt_published DESC, o il primo record inviato ci dovrebbe essere inferiore a record 500 nella tabella.

  • Recupera tutti i record inviati entro e non oltre il data l'ultimo record selezionato. Dal momento che DATE(x) è sempre minore o uguale a x, non ci può essere più di record 500, ma ancora molto meno di quanto l'intera tabella.

  • Ordini e limiti di questi record a seconda dei casi.

Si possono trovare interessante questo articolo, in quanto copre un problema simile:

Altri suggerimenti

Può essere necessario un indice su dt_published. Potresti postare i piani di query per le due query?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top