2011-12-13 103 views
6

可能重複:
Default sort-ordering in MySQL (ALTER TABLE … ORDER BY …;)MySQL的默認順序取決於WHERE

我有這樣的一個表:

CREATE TABLE IF NOT EXISTS `table_test` (
    `id` mediumint(8) unsigned NOT NULL, 
    `country` enum('AF','AX','AL') DEFAULT NULL, 
    `number` tinyint(3) unsigned DEFAULT NULL, 
    `sort_order` double unsigned NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`), 
    KEY `country` (`country`), 
    KEY `id` (`id`,`country`) 
) ENGINE=MEMORY DEFAULT CHARSET=latin1; 

我有我換了一臺默認排序如:

ALTER TABLE test_table ORDER BY sort_order ASC; 

該表從不更新,並且在其生命週期中不刪除或添加任何記錄。這一切似乎工作,所以如果我使用以下查詢:

SELECT * FROM test_table LIMIT 10 

它以正確的順序返回10條記錄。

即使我用:

SELECT * FROM test_table WHERE num=3 

返回正確的順序的結果。

但如果我這樣做

SELECT * FROM test_table WHERE country='AX' 

它將返回以相反的順序結果。

有人能告訴我這是怎麼發生的嗎?

+0

'country'被編入索引,可能'country'索引與sort_order不同,或者它根本沒有排序。或者在你的情況下,它意外地反向排序... – Vili

+0

_ORDER BY對於包含用戶定義的聚簇索引(PRIMARY KEY或NOT NULL UNIQUE索引)的InnoDB表沒有意義。 InnoDB總是按照這樣的索引排序錶行,如果有的話。 - - http://dev.mysql.com/doc/refman/5.1/en/alter-table.html - 我知道你的表引擎是MEMORY,但是我認爲案件是一樣的。 – Vili

+0

這似乎是類似於:http://stackoverflow.com/questions/725717/default-sort-ordering-in-mysql-alter-table-order-by ..除了從文檔:請注意,該表不保留按照此順序插入和刪除。這個選項主要用於當你知道你主要是在大部分時間以特定順序查詢行時。在對錶格進行重大更改後使用此選項,您可能會獲得更高的性能。在某些情況下,如果表格按照您希望稍後訂購的列順序排列,可能會使MySQL的排序更容易...可能,May ...不要依賴 – xQbert

回答

5

在表上指定ORDER BY只是幫助引擎加快查詢的順序。它不會強制mysql總是以相同的順序返回結果。

在此描述:。http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

「ORDER BY,可以創建新表,在一個特定的順序排注意,表不留在這個順序插入和刪除後,此選項很有用主要是當你知道你主要是按照特定的順序查詢行時,通過在對錶進行重大更改後使用這個選項,你可能會獲得更高的性能,在某些情況下,它可能會使排序更容易對於MySQL而言,如果表格按照您希望稍後訂購的列的順序排列「

因此,您也必須在查詢中使用ORDER BY表達式。

+0

+1如果它不夠清楚:*默認順序的概念*在SQL語言中不存在這是故意的和設計的 –

+0

IMO更好的答案,因爲它站點的文檔的引用他們,並表明直接向所有查詢添加秩序 – xQbert

+0

這並不回答任務離子爲什麼會發生。我不想知道它是否是首選的方式,但我需要知道引擎爲什麼決定顛倒排序順序。此外,文檔沒有聲明我應該在查詢 – Nin

1

爲什麼不嘗試查詢這樣的:

SELECT * FROM test_table ORDER BY sort_order ASC LIMIT 10; 
SELECT * FROM test_table WHERE num=3 ORDER BY sort_order ASC; 
SELECT * FROM test_table WHERE country='AX' ORDER BY sort_order ASC; 
+1

,因爲這不是問題。問題是爲什麼MYSQL在允許缺省訂單的表上有一個功能,如果它不起作用的話。 (或者爲什麼它不是在執行 – xQbert

+0

以及我知道按順序應該在結果集上工作。我第一次聽到你可以在alter語句中進行排序。如果我得到解決方案,我正在嘗試閱讀它我只會讓你知道.. –

3

我猜你的索引的默認順序上國家是DESC。正因爲如此,如果使用這一個,你會得到「錯誤」的順序,在所有其他情況下,它是不同的。不知道是否可以在mysql中指定索引的順序,但我認爲是。

但仍然不知道如果你可以依賴的順序,如果你不指定一個。只需將ORDER BY語句添加到所有查詢中。

+0

'只需將ORDER BY語句添加到所有查詢中.'這是正確的答案。SQL ** never **保證結果集的任何特定順序,除非您使用'ORDER BY'子句,這些行在物理上存儲在表中的順序並不重要 – Hammerite

+0

並且MySQL不**具有'DESC'索引 –

1

您看到此行爲的原因大概如下:由於WHERE子句按country進行過濾,因此MySQL使用country上的索引來查找要返回的行。索引行很可能按照country排序,然後是id(表的主鍵)。這意味着MySQL檢索行的最有效方式是通過讀取索引引用的行,索引中出現的順序。因此,這些行在磁盤上出現的順序是不相關的。

的MySQL確實提供了語法允許您指定索引的順序,但this is currently ignored

的index_col_name規約可以以ASC或DESC結束。這些關鍵字可用於將來的擴展,用於指定升序或降序索引值存儲。目前,他們被解析但被忽略;索引值始終以升序存儲。

您必須將ORDER BY子句添加到您的查詢中,以確保行按所需順序返回。順便說一句,無論如何,情況總是如此。 SQL不保證以任何特定順序返回行,無論這些行是如何物理存儲的(除非存在ORDER BY子句)。

+0

中使用ORDER BY。如果是這種情況,它應該以隨機順序顯示sort_order,但它會以DESC順序完美顯示它。 – Nin

+1

僅僅因爲它的順序並不是你想要的,並不意味着它是*隨機*順序。 MySQL以最方便的方式向您展示它。當表格按照DESC順序排列時,恰好發生該順序與您想要的順序一致。 – Hammerite