在BigQuery中优化查询

时间:2015-10-22 11:35:53

标签: sql google-bigquery

我正在尝试在BigQuery中运行查询但是我收到“在查询执行期间超出资源”。

实际上,我有两张桌子:

Table user:
Id  | User   | Latitude  | Longitude
1   | 1      |  50.83    |  4.01
2   | 1      |  50.84    |  4.03
3   | 2      |  48.78    |  2.87
4   | 3      |  47.42    |  8.53
…
Table point_of_interest:
Id  | Latitude  | Longitude | Range   |  Tag  
1   |  50.81    |  3.98     |  0.05   |  a;b;c;d
2   |  50.85    |  4.03     |  0.025  |  a;c;e;f
3   |  40.80    |  3.87     |  0.04   |  a;d;g
4   |  47.42    |  8.57     |  0.08   |  b
…

目的是连接表格以标记纬度,经度和范围的所有用户。

为此,我使用了那个查询:

SELECT
  u.User AS id,
  GROUP_CONCAT(poi.Tag) AS tag
FROM (
  SELECT
    u.User,
    poi.Tag,
  FROM
    [user] u
  CROSS JOIN
    [point_of_interest] poi
  WHERE
    u.Latitude BETWEEN poi.Latitude – poi.Range AND poi.Latitude + poi.Range
    AND
    u.Longitude BETWEEN poi.Longitude – poi.Range AND poi.Longitude + poi.Range )
GROUP BY
  id

用户表目前是520 MB,point_of_interest表只有565 KB,但可能会在当时增长。

我想知道是否有更好的方法来实现这一目标,以及最佳架构。

编辑:

我也尝试使用范围LEFT JOIN EACH,但BigQuery仅支持ON关键字后的等式语句。

2 个答案:

答案 0 :(得分:1)

您需要对表进行分片并运行多个较小的查询。

这样的事情:

for (int i = 1; i <= 10; i++)
                {
                    switch (i)
                    {
                        case 1:
                            if (count1 > 0)
                            {
                                PieChart1.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
                                {
                                    Category = "1",
                                    Data = count1
                                });
                            }
                            break;
                        case 2:
                            if (count2 > 0)
                            {
                                PieChart1.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
                                {
                                    Category = "2",
                                    Data = count2
                                });
                            }
                            break;
                        case 3:
                            if (count3 > 0)
                            {
                                PieChart1.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
                                {
                                    Category = "3",
                                    Data = count3
                                });
                            }
                            break;
                        case 4:
                            if (count4 > 0)
                            {
                                PieChart1.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
                                {
                                    Category = "4",
                                    Data = count4
                                });
                            }
                            break;
                        case 5:
                            if (count5 > 0)
                            {
                                PieChart1.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
                                {
                                    Category = "5",
                                    Data = count5
                                });
                            }
                            break;
                        case 6:
                            if (count6 > 0)
                            {
                                PieChart1.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
                                {
                                    Category = "6",
                                    Data = count6
                                });
                            }
                            break;
                        case 7:
                            if (count7 > 0)
                            {
                                PieChart1.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
                                {
                                    Category = "7",
                                    Data = count7
                                });
                            }
                            break;
                        case 8:
                            if (count8 > 0)
                            {
                                PieChart1.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
                                {
                                    Category = "8",
                                    Data = count8
                                });
                            }
                            break;
                        case 9:
                            if (count9 > 0)
                            {
                                PieChart1.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
                                {
                                    Category = "9",
                                    Data = count9
                                });
                            }
                            break;
                        case 10:
                            if (count10 > 0)
                            {
                                PieChart1.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
                                {
                                    Category = "10",
                                    Data = count10
                                });
                            }
                            break;
                    }

但你需要在我的例子中找到一个不错的高数字,而不是100,并编写一段代码为你自动化。首先手动尝试一个分片,并在分片中留出适当的记录边距。

您可以将SELECT * FROM table WHERE ABS(HASH(id) % 100) == 0 SELECT * FROM table WHERE ABS(HASH(id) % 100) == 1 SELECT * FROM table WHERE ABS(HASH(id) % 100) == 2 SELECT * FROM table WHERE ABS(HASH(id) % 100) == 3 ... SELECT * FROM table WHERE ABS(HASH(id) % 100) == 99 结果放入同一目标表中,并与原始数据分开存储。

答案 1 :(得分:0)

对于类似的问题,我通过为每一行生成键来优化它,可以用来避免对整个数据集进行CROSS JOIN。

http://googlecloudplatform.blogspot.com/2014/03/geoip-geolocation-with-google-bigquery.html

StackO:How to improve performance of GeoIP query in BigQuery?

顺便问一下,这个问题与稍后发布的问题(Tag huge list of elements with lat/long with large list of geolocation data)有关吗?