0

結合されている場合はファイルソートを使用するこのクエリがありますが(ユニオンオール)、個別に実行するとファイルソートなしで正常に動作します。ここでは、個別に実行したくありませんが、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 
4

2 に答える 2

0

@フェデリコ

「すべての UNION が一時テーブルを使用する古い MySQL バグもあります: http://bugs.mysql.com/bug.php?id=50674およびクエリによって生成された一時テーブルの順序はファイルソートを意味します」

コメントではコードの書式設定が許可されていないため、回答を作成しました

C++ ソース コード オフ (ファイル sql/sql_union.cc) MySQL 5.5.32 ユニオンは、常に一時テーブルを作成するように見えます。コード コメントと関数 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)))
于 2013-10-18T10:37:44.000 に答える
0

唯一の違いは WHERE 句のように思えます。OR を使用するだけです。

また、このコンテキストでは ORDER BY は実行されません。これは、MySQL にバグがあるためではなく、論理的な意味がないためです。

また、すべての UNION が一時テーブルを使用する古い MySQL のバグもあります: http://bugs.mysql.com/bug.php?id=50674 クエリによって生成された一時テーブルの順序付けはファイルソートを意味します

于 2013-10-18T10:09:13.267 に答える