SqlServer无法处理多个查询

时间:2017-02-08 08:39:21

标签: java c# mysql sql-server parallel-processing

在我的应用上进行负载测试时,我看到了一个巨大的减速。 我有一个大约需要350ms才能运行的查询,但我并行运行了8次(更不用说32次),它最多可以运行2.5秒。

我在分析器上验证了执行确实占用了时间。

查询:

SELECT SUM([_Facts_].[Sales]) [_measures___Sum Sales_], [_Date_].[year] [_Date___year_]
FROM [pp].[Facts] [_Facts_], [pp].[Date] [_Date_]
WHERE [_Facts_].[dateKey] = [_Date_].[dateKey]
GROUP BY [_Date_].[year]
ORDER BY [_Date_].[year] ASC

我正在运行8个并行进程,按顺序进行10次调用。 对于1个并行,我得到:

360, 350, 345, 360, 365, 360, 395, 786, 395, 370, avg:408

8平行:

515, 1571, 1471, 1326, 1862, 2478, 1922, 3098, 2413, 2032, 2773, 3048, 2453, 2092, 2077, 3359, 2898, 2733, 3018, 2483, 1887, 3023, 3088, 3724, 2317, 2753, 2643, 3284, 3299, 2418, 1907, 1862, 2498, 2838, 2518, 3203, 2613, 2207, 3434, 2613, 3198, 2257, 2593, 2448, 2518, 2968, 2828, 2122, 2963, 2212, 3299, 2988, 3153, 2803, 2157, 2543, 2758, 2998, 2538, 2257, 2788, 2443, 2082, 2613, 3173, 4205, 2603, 2387, 1747, 3854, 3068, 2788,  2603, 3103, 2703, 3198, 1832, 1421, 2217, 1326

平均:

2535, 2523, 2571, 2627, 2689, 2469, 2521, 2610

当平行进入16时,它甚至更多。

我尝试在MySql上进行测试并得到相同的跳转(不同的测试时间,但并行时至少慢4倍)。

这些数据库无法处理负载吗?!

在C#和Java中都会发生这种情况: C#:

class Program
{
    static void Main(string[] args)
    {
        Parallel.For(0, 8, i => run());
    }

    static void run()
    {
        using (var conn = new SqlConnection("Data Source=.;Initial Catalog=;User ID=;Password="))
        {
            conn.Open();

            var cnt = 10;

            long avg = 0;

            for (int i = 0; i < cnt; i++)
            {
                var sw = DateTime.Now.Ticks;

                using (var cmd = new SqlCommand("SET ARITHABORT ON", conn))
                {
                    cmd.CommandText =
                        "SELECT SUM([_Facts_].[Sales]) [_measures___Sum Sales_], [_Date_].[year] [_Date___year_]\n" +
                        "FROM [pp].[Facts] [_Facts_], [pp].[Date] [_Date_]\n" +
                        "WHERE [_Facts_].[dateKey] = [_Date_].[dateKey] \n" +
                        "GROUP BY [_Date_].[year]\n" +
                        "ORDER BY [_Date_].[year] ASC";

                    using (var reader = cmd.ExecuteReader())
                    {
                        var x = 0;
                        while (reader.Read())
                        {
                            x++;
                        }

                        reader.Close();
                    }

                }

                var dif = (DateTime.Now.Ticks - sw) / 1000;
                avg += dif;
                Console.WriteLine(dif);
            }

            conn.Close();

            Console.WriteLine("avg:" + avg / cnt);
        }
    }
}

爪哇:

@Test
public void asdf() throws SQLException {

   Runnable r = () -> {
      try (Connection conn = DriverManager.getConnection("jdbc:sqlserver://;databaseName=", "", "")) {

         long avg = 0;

         for (int i = 0; i < 10; i++) {

            try (Statement statement = conn.createStatement()) {
               StopWatch sw = new StopWatch();
               sw.start();

               ResultSet resultSet = statement.executeQuery("SELECT SUM([_Facts_].[Sales]) [_measures___Sum Sales_], [_Date_].[year] [_Date___year_]\n" +
                     "FROM [pp].[Facts] [_Facts_], [pp].[Date] [_Date_]\n" +
                     "WHERE [_Facts_].[dateKey] = [_Date_].[dateKey] \n" +
                     "GROUP BY [_Date_].[year]\n" +
                     "ORDER BY [_Date_].[year] ASC");

               int x = 0;
               while (resultSet.next()) {
                  x++;
               }

               sw.stop();
               avg+=sw.getTime();
               System.out.println(sw);
            }
         }

         System.out.println(avg/10);

      } catch (SQLException e) {
         e.printStackTrace();
      } finally {

      }
   };



   ExecutorService executor = Executors.newFixedThreadPool(8);
   for (int i = 0; i < 8; i++) {
      executor.execute(r);
   }


   try {
      executor.shutdown();
      executor.awaitTermination(12312313, TimeUnit.MINUTES);
   } catch (InterruptedException e) {
      e.printStackTrace();
   }
}

更多信息

这两个表是~1,000行和〜420,000行。连接约为420,000行,结果为3行。

在date.dateKey和FK上有关于事实的PK。这些是表格,而不是观点。

我查看了探查器以确认持续时间是查询的实际执行时间,而不是应用程序的运行时间。

SqlServer有16个内核,所以我希望8个查询并行运行而不会堆叠。

在服务器上,1次查询的CPU最高可达50%。对于8,它达到了95%。

网络/内存/ IO似乎没有太大变化。

plan

0 个答案:

没有答案