2013-10-18 54 views
0

請讓我有這個查詢使用filesort如果組合(聯合所有),但如果單獨執行工作正常沒有文件排序。在這裏,我不想單獨執行它,但想要實現union all選項。請有人幫忙。如何避免聯合所有查詢上的文件夾

(SELECT STRAIGHT_JOIN *, 
        topic_post_time, 
        topic_title, 
        topic_id       AS tid, 
        p.userid       AS profile_id, 
        Concat(first_name, ' ', last_name) AS poster_name, 
        Concat(first_name, '.', last_name) AS profile_name, 
        forum_id, 
        topic_last_post_time, 
        sch_name_abbrev, 
        picture_small_url, 
        profile_pix_upload_path, 
        profile_pix_upload_path, 
        LEFT(post_text, 100)    AS post_text 
FROM _forum_topics FORCE INDEX(topic_poster) 
    INNER JOIN _profile p 
      ON (p.userid = _forum_topics.topic_poster) 
    INNER JOIN _users 
      ON p.userid = _users.userid 
    INNER JOIN _class 
      ON _users.classid = _class.classid 
    INNER JOIN _unit 
      ON _class.unitid = _unit.unitid 
    INNER JOIN _department 
      ON _unit.deptid = _department.deptid 
    INNER JOIN _faculty 
      ON _department.facid = _faculty.facid 
    INNER JOIN _university 
      ON (_faculty.schid = _university.schid) 
WHERE _forum_topics.sub_forum_id IN(133, 134, 135, 136, 
            137, 138) 
ORDER BY topic_last_post_time DESC 
LIMIT 0, 20) 
UNION ALL 
(SELECT STRAIGHT_JOIN *, 
        topic_post_time, 
        topic_title, 
        topic_id       AS tid, 
        p.userid       AS profile_id, 
        Concat(first_name, ' ', last_name) AS poster_name, 
        Concat(first_name, '.', last_name) AS profile_name, 
        forum_id, 
        topic_last_post_time, 
        sch_name_abbrev, 
        picture_small_url, 
        profile_pix_upload_path, 
        profile_pix_upload_path, 
        LEFT(post_text, 100)    AS post_text 
FROM _sch_forum_topics s FORCE INDEX(topic_poster) 
    INNER JOIN _profile p 
      ON (p.userid = s.topic_poster) 
    INNER JOIN _users 
      ON p.userid = _users.userid 
    INNER JOIN _class 
      ON _users.classid = _class.classid 
    INNER JOIN _unit 
      ON _class.unitid = _unit.unitid 
    INNER JOIN _department 
      ON _unit.deptid = _department.deptid 
    INNER JOIN _faculty 
      ON _department.facid = _faculty.facid 
    INNER JOIN _university 
      ON _faculty.schid = _university.schid 
ORDER BY topic_last_post_time DESC 
LIMIT 0, 20) 
LIMIT 
0, 20 
+1

我是正確,查詢中唯一的區別是WHERE條件? – scones

+0

是文件放慢執行時間?因爲filesort通常不會因爲記錄數較低而減慢記錄「Using temporary; Using filesort」可能很糟糕,因爲它可能會導致臨時MyISAM文件需要使用隨機磁盤讀取I/O的快速排序算法和隨機數寫入I/O公式(假設快速排序最佳情況和4 ms磁盤隨機訪問(10K磁盤))((20 log 20)* 0.004)〜0.1秒 –

+0

但是,如果文件排序算法得到錯誤的估計值,記錄/來自MySQL優化器的行.. STRAIGHT_JOIN可能是一個原因。 –

回答

0

在我看來,唯一的區別是WHERE子句。只需使用一個OR。

另外,ORDER BY在這種情況下並不完成,並不是因爲MySQL有缺陷,而是因爲它沒有邏輯意義。

還有一箇舊版本的MySQL錯誤,這使所有的UNION使用臨時表: http://bugs.mysql.com/bug.php?id=50674 和訂購查詢生成的臨時表文件排序

0

意味着@Federico

「還有一箇舊版本的MySQL使所有UNION使用臨時表的錯誤:http://bugs.mysql.com/bug.php?id=50674和訂購由查詢生成的臨時表格意味着文件夾「

我做了一個anwser,因爲註釋允許代碼摳圖

C++源代碼關閉(文件SQL/sql_union.cc)MySQL的32年5月5日聯合看起來總是創建一個臨時表.. 參見代碼中的註釋和功能create_tmp_table

/* 
    Create a temporary table to store the result of select_union. 

    SYNOPSIS 
    select_union::create_result_table() 
     thd    thread handle 
     column_types  a list of items used to define columns of the 
         temporary table 
     is_union_distinct if set, the temporary table will eliminate 
         duplicates on insert 
     options   create options 

    DESCRIPTION 
    Create a temporary table that is used to store the result of a UNION, 
    derived table, or a materialized cursor. 

    RETURN VALUE 
    0     The table has been created successfully. 
    1     create_tmp_table failed. 
*/ 

bool 
select_union::create_result_table(THD *thd_arg, List<Item> *column_types, 
            bool is_union_distinct, ulonglong options, 
            const char *alias) 
{ 
    DBUG_ASSERT(table == 0); 
    tmp_table_param.init(); 
    tmp_table_param.field_count= column_types->elements; 

    if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types, 
           (ORDER*) 0, is_union_distinct, 1, 
           options, HA_POS_ERROR, alias)))