查询需要很长时间才能执行

时间:2018-06-19 02:31:01

标签: mysql sql mysql-workbench

我有一个查询,我正在尝试执行此刻,但在让它加载几分钟之后,我认为可能是我做错了。

以下是我要执行的内容:

SELECT *
FROM open_hours
INNER JOIN open_times
    ON open_hours.id = open_times.open_hour_id
INNER JOIN off_peak_times
    ON open_hours.id = off_peak_times.open_hour_id;

我有三张桌子:

OPEN_HOURS:

大约14k行

id;
owner_type;
owner_id;
seats;
time_interval;
max_at_one_time;
created_at;
updated_at;
minutes_in_advance;

open_times:

大约18k行

id;
open_hour_id;
time_start;
time_end;
weekday;
created_at;
meal_type;

off_peak_times:

大约10k行

id;
open_hour_id;
time;
discount;
seats;
created_at;
updated_at;
weekday;

我已经尝试将SELECT *缩小为SELECT open_hours.id,open_times.meal_type,因为实际上这是我现在试图获得的唯一数字。它在大约30秒内得到了我的结果,这对我来说仍然听起来很多。

我在其他更大的桌子上运行其他查询,但几乎立即得到结果,那么有什么我缺少或不考虑的事情吗?

3 个答案:

答案 0 :(得分:2)

运行此

更改表open_times添加索引(open_hour_id);

更改表off_peak_times添加索引(open_hour_id);

然后再次运行您的查询。这些是足够小的表,我现在不用担心你的执行计划。我想你会发现这会加速它。

答案 1 :(得分:0)

要进一步分析,了解查询行为和表信息非常重要。这可以执行以下语句:

    // Test array.
    String[][] test = { { "Bill", "Jones" }, { "Janet", "Kline" }, { "George", "Bailey" },
            { "Ellan", "Sanches" }, { "Tom", "Nguyen" }, { "William", "Walters" }, { "Author", "James" },
            { "Henry", "Daniels" }, { "Mike", "Franklin" }, { "Julie", "Andrews" } };

    // Print unsorted array.
    System.out.println("Unsorted array:");
    for (String[] strArr : test)
    {
        System.out.println(strArr[0] + " " + strArr[1]);
    }

    Scanner input = new Scanner(System.in);
    Comparator<String[]> c;

    // Loop until correct input.
    while (true)
    {
        System.out.println("Sort by first name or last name?");
        System.out.println("Type f for first name, or l for last name.");
        String in = input.nextLine();
        if (in.equals("f"))
        {
            // Set comparator to compare by first name then last name.
            c = (a1, a2) ->
            {
                int result = a1[0].compareTo(a2[0]);
                if (result == 0)
                {
                    result = a1[1].compareTo(a2[1]);
                }
                return result;
            };
            break;
        }
        if (in.equals("l"))
        {
            // Set comparator to compare by last name then first name.
            c = (a1, a2) ->
            {
                int result = a1[1].compareTo(a2[1]);
                if (result == 0)
                {
                    result = a1[0].compareTo(a2[0]);
                }
                return result;
            };
            break;
        }
        System.out.println("Illegal input. Please try again.");
    }

    // Sort.
    Arrays.sort(test, c);

    // Print sorted array.
    System.out.println("Sort complete. Sorted array:");
    for (String[] strArr : test)
    {
        System.out.println(strArr[0] + " " + strArr[1]);
    }

此外,对于所涉及的每个唯一表:

EXPLAIN EXTENDED SELECT * FROM open_hours INNER JOIN open_times ON open_hours.id = open_times.open_hour_id INNER JOIN off_peak_times ON open_hours.id = off_peak_times.open_hour_id\G
SHOW WARNINGS \G
EXPLAIN FORMAT=JSON SELECT * FROM open_hours INNER JOIN open_times ON open_hours.id = open_times.open_hour_id INNER JOIN off_peak_times ON open_hours.id = off_peak_times.open_hour_id\G           -- MYSQL 5.6+ only

答案 2 :(得分:0)

为了使您的查询更快,您可以做三件事。 不知道它会对你有所帮助,但根据SQL优化查询概念,它必须有所帮助。

  1. 为您的所有表创建CLUSTERED INDEX。群集索引使SELECT查询在比率为30:70时更快。
  2. 您应该列出列表而不是STAR语句(避免SELECT *)。额外的列使BUFFER-POOL变重。
  3. 您可以使用VIEW而不是查询。因为JOIN语句中的VIEW优于普通查询。
  4. 从三个以上,您必须尝试第一个选项(CLUSTER INDEX),这将真正提高性能。 希望这会有所帮助。