Mysql

如何使用變數記憶體選擇?(MySQL)

  • December 6, 2016

語境:

我經常執行複雜的查詢:

CREATE OR REPLACE VIEW ordered_words AS SELECT word.id
 FROM category JOIN frequency ON category.id = frequency.category_id
   JOIN word ON frequency.word_id = word.id
   JOIN language ON word.language_id = language.id
 WHERE
   category.name='Subtitles' AND iso_639_1='en'
 ORDER BY frequency.value DESC;

我啟用了記憶體query_cache_type=1,我獲得了很大的性能提升。

第一次(4.5 秒)

sql> SELECT * FROM ordered_words
500 rows retrieved starting from 1 in 4s 585ms (execution: 4s 576ms, fetching: 9ms)

第二次(5 毫秒)

sql> SELECT * FROM ordered_words
500 rows retrieved starting from 1 in 11ms (execution: 5ms, fetching: 6ms)

沒關係。


問題

但是現在我想在這個結果中添加一個標識符為 1,2,3 的列……因為我希望能夠從這個查詢的結果中獲取選定的行。我創建了以下查詢:

SELECT @ROW := @ROW + 1 AS ROW
FROM ordered_words t
join (SELECT @ROW := 0) t2;

但是這個查詢沒有被記憶體。任何時候執行大約需要 4.8 秒。我想保存到這個查詢的記憶體結果。

替代解決方案:

因為我在數據庫方面的經驗很少。我不知道我的方法是否最佳,所以我描述了更廣泛的背景。在我的應用程序中,很少使用插入。

我的真正目標是經常執行查詢,從ordered_words動態分配的機率分佈中獲取一個隨機元素。我不想為此創建新表,因為類別和語言是自由參數。我將使用函式。但我不想隨時執行所有查詢。

隨機化的邏輯將在 MySQL 之外執行。MySQL 將僅獲取保存在結果中的時間順序的單詞數ordered_words。我計劃將列row視為臨時標識符,允許word_id在不計算所有連接和從第一次提到的查詢中排序的情況下進行選擇。

也許在記憶體中創建了臨時表之類的東西,或者我應該使用其他數據庫系統嗎?

圖式


更新

正如@Rick-James 建議的那樣。時機不對。記憶體是由我的 IDE 創建的——DataGrip 不是由 MySQL 創建的。最後我決定通過命令將復雜查詢的結果保存到記憶體中的表中:

 CREATE TABLE IF NOT EXISTS words_memory_subtitles_en (id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, word_id INTEGER)
 ENGINE=MEMORY
 AS
 SELECT word.id as word_id
   FROM category JOIN frequency ON category.id = frequency.category_id
     JOIN word ON frequency.word_id = word.id
     JOIN language ON word.language_id = language.id
   WHERE
     category.name='Subtitles' AND iso_639_1='en'
   ORDER BY frequency.value DESC;

我將在 PHP 中管理創建和刪除這樣的表。

我決定idfrequency表中刪除。

為了有效地獲取隨機行,這裡有一個關於此類的部落格。

您是否真的選擇了所有行的所有列,如您提到的時間所示?

請記住,只要在該表上發生任何寫操作,就會刪除“查詢記憶體”中給定表的所有條目。(這使得 QC 在繁忙的生產伺服器中很少使用。)

多對多表中的一個常見錯誤是有一個AUTO_INCREMENTid。在此處查看該和其他許多:許多提示

VIEWs是一種方便,而不是一種提高效率的方法。假裝你沒有VIEW,寫下你需要的真正的查詢。如果它“足夠快”,那麼我已經給了你答案。如果沒有,讓我們看看它並尋找優化它的方法。請提供SHOW CREATE TABLE每個相關表格。

引用自:https://dba.stackexchange.com/questions/157360