2013-08-20 31 views
1

這裏是我的情況:MySQL的臨時表的性能

我的建築內,可以由用戶自由添加大量的搜索條件的產品目錄系統,通過直接請求或用戶的權限,位置或其他元數據。

  1. 有一個主要的查詢正在做繁重的工作,它比較大,並且包含了可變數量的子查詢以使魔法發生。查詢返回9列,其中沒有包含太多數據,其中一些通常只是空值。

  2. 我需要在隨後的幾個其他查詢(例如,排序結果數據,應用第二層過濾器,分頁,選擇備用過濾器選項)中訪問此查詢的結果數據。

  3. 在PHP方面,我只需要25個項目的分頁結果,所以我想保留我的數據庫數據在數據庫中。

我正在使用的解決方案是創建一個臨時表,並向其中插入/選擇數據。

CREATE TEMPORARY TABLE `tmp_table` 
(
    `col1` bigint(20) NOT NULL, 
    `col2` int(11) NOT NULL, 
    `col3` varchar(16) NOT NULL, 
    `col4` decimal(10,2) NULL, 
    `col5` decimal(10,2) NULL, 
    `col6` decimal(10,2) NULL, 
    `col7` decimal(10,2) NULL, 
    `col8` decimal(10,2) NULL, 
    `col9` tinyint(1) NULL, 
    `col10` int(11) NULL, 
    `col11` int(11) NULL 
) ENGINE=MEMORY; 

INSERT INTO `tmp_table` (col1, col2, etc.) 
SELECT [...large query] 

問題:通過自身的大型查詢執行< 0.3秒,但是增加臨時表的插入推動執行了3.5秒之間〜5.0S

我已經試過MEMORY,InnoDB的,和MyISAM作爲表引擎,都有類似的結果。

我已經嘗試過在臨時表上使用和沒有索引,這似乎也沒有影響執行時間。

的執行時間幾乎是一個結果集的50或500

我的問題是一樣的:這是不合適的做法?是否有任何MySQL配置變量可以提高性能?有沒有更好的解決方案,我忽略了?

+0

您是否將InnoDB配置爲使用比默認8MB的內存更多的內存? –

+0

是的,innodb_buffer_pool_size是20GB。 – Inkuisi

回答

0

您可以爲會話ID添加另一列給您的表,並使其非臨時。然後,第一個查詢將只是將其數據插入到此表中,並且有時您會清除它,爲過期的會話刪除數據。這避免了爲每個請求創建表的開銷。

也許,在插入之前,您可能還要刪除所有會話特定的數據。

+0

這是我考慮過的解決方案之一,但是每個請求的結果集會有所不同,以至於數據將在大部分時間被替換。 – Inkuisi

+0

正如我所理解的,您的請求是緩存大量查詢的輸出,以查找幾個使用它作爲基礎的查詢。也許即使這樣也會節省時間,而且你也可以。 G。在最後一個輔助查詢完成後總是刪除數據。特別是因爲您不必將數據發送到您的Web服務器,但可以將它們本地保留在數據庫中。 – FrankPl