查询数据
本教程演示如何使用 SQL 查询 Apache Druid 中的数据。
它假设您已经完成了快速入门或以下教程之一,因为我们将查询您在按照这些教程操作时所创建的数据源。
运行 Druid SQL 查询有多种方式:通过 Web 控制台、使用命令行工具以及通过 HTTP 发送查询。我们将逐一介绍这些方式。
从 Web 控制台查询 SQL
Web 控制台包含一个视图,可以更轻松地构建和测试查询,并查看其结果。
-
如果 Druid 集群尚未运行,请启动它,并在浏览器中打开 Web 控制台。
-
单击标题中的 Query(查询)以打开查询视图。

您可以随时在编辑窗格中直接编写查询,但查询视图也提供了有助于您构建 SQL 查询的工具,我们将使用它们来生成一个入门查询。
-
展开左侧窗格中的 wikipedia 数据源树。我们将为 page 维度创建一个查询。
-
单击
page,然后从菜单中选择 Show:page。
查询编辑窗格中会出现一个 SELECT 查询并立即运行。但是,在这种情况下,查询不会返回任何数据,因为默认情况下该查询会过滤过去一天的数据,而我们的数据要久远得多。让我们删除过滤器。
-
单击 Run(运行)以执行查询。
现在您应该会看到两列数据:页面名称和计数。

请注意,由于 Smart query limit(智能查询限制)功能,控制台中的结果默认限制为一百条左右。这有助于用户避免无意中运行返回过多数据的查询,从而可能导致系统不堪重负。
-
让我们直接编辑该查询,并查看编辑器中更多的查询构建功能。单击查询编辑窗格并进行以下更改:
-
在第一列
"page"之后添加一行,并开始输入新列的名称"countryName"。请注意,自动完成菜单会建议列名、函数、关键字等。选择 "countryName",并通过名称或位置引用2,将新列添加到 GROUP BY 子句中。 -
为了提高可读性,将
Count列名替换为Edits,因为COUNT()函数实际上返回的是该页面的编辑次数。在 ORDER BY 子句中也进行同样的列名更改。COUNT()函数是 Druid SQL 查询中可用的众多函数之一。您可以将鼠标悬停在自动完成菜单中的函数名称上以查看简短说明。此外,您可以在 Druid 文档中找到更多信息;例如,COUNT()函数记录在聚合函数中。
现在查询应该如下所示:
SELECT
"page",
"countryName",
COUNT(*) AS "Edits"
FROM "wikipedia"
GROUP BY 1, 2
ORDER BY "Edits" DESC当您再次运行查询时,请注意我们获得了新的维度
countryName,但对于大多数行来说,其值为 null。让我们只显示具有countryName值的行。 -
-
单击左侧窗格中的
countryName维度并选择第一个过滤选项。它可能不是我们完全想要的,但我们将手动对其进行编辑。新的 WHERE 子句应出现在您的查询中。 -
修改 WHERE 子句以排除没有 countryName 值的行。
WHERE "countryName" IS NOT NULL再次运行查询。现在您应该会看到按国家/地区划分的编辑排名。

-
在后台,每个 Druid SQL 查询在数据节点上运行之前,都会被转换为基于 JSON 的 Druid 原生查询格式。您可以通过单击
...并选择 Explain SQL Query(解释 SQL 查询)来查看此查询的原生查询。虽然您可以将 Druid SQL 用于大多数目的,但熟悉原生查询对于编写复杂查询和排查性能问题非常有用。有关详细信息,请参阅原生查询。

查看执行计划的另一种方法是在查询前面加上 EXPLAIN PLAN FOR,如下所示:
EXPLAIN PLAN FOR
SELECT
"page",
"countryName",
COUNT(*) AS "Edits"
FROM "wikipedia"
WHERE "countryName" IS NOT NULL
GROUP BY 1, 2
ORDER BY "Edits" DESC
这在从命令行或通过 HTTP 运行查询时特别有用。
- 最后,单击
...并选择 Edit context(编辑上下文)以了解如何添加控制查询执行的其他参数。在字段中,输入 JSON 键值对形式的查询上下文选项,具体如设置查询上下文中所述。
就是这样!我们使用 Web 控制台中内置的一些查询构建功能构建了一个简单的查询。以下部分提供了更多您可以尝试的查询示例。
请参阅通过 HTTP 查询 SQL,获取如何使用 Druid SQL HTTP API 的示例。
更多 Druid SQL 示例
尝试以下查询以学习更多 Druid SQL 技巧:
随时间查询
SELECT FLOOR(__time to HOUR) AS HourTime, SUM(deleted) AS LinesDeleted
FROM wikipedia WHERE TIME_IN_INTERVAL("__time", '2016-06-27/2016-06-28')
GROUP BY 1

常规分组查询
SELECT channel, page, SUM(added)
FROM wikipedia WHERE TIME_IN_INTERVAL("__time", '2016-06-27/2016-06-28')
GROUP BY channel, page
ORDER BY SUM(added) DESC

通过 HTTP 查询 SQL
您可以直接通过 HTTP 向 Druid Broker 提交原生查询。请求主体应为 JSON 对象,其中 query 键的值包含查询文本。
{
"query": "SELECT page, COUNT(*) AS Edits FROM wikipedia WHERE TIME_IN_INTERVAL(\"__time\", '2016-06-27/2016-06-28') GROUP BY page ORDER BY Edits DESC LIMIT 10"
}
教程包中包含一个示例文件,其中包含了上述 SQL 查询,位于 quickstart/tutorial/wikipedia-top-pages-sql.json。让我们将该查询提交给 Druid Broker。
curl -X 'POST' -H 'Content-Type:application/json' -d @quickstart/tutorial/wikipedia-top-pages-sql.json https://:8888/druid/v2/sql
应返回以下结果:
[
{
"page": "Copa América Centenario",
"Edits": 29
},
{
"page": "User:Cyde/List of candidates for speedy deletion/Subpage",
"Edits": 16
},
{
"page": "Wikipedia:Administrators' noticeboard/Incidents",
"Edits": 16
},
{
"page": "2016 Wimbledon Championships – Men's Singles",
"Edits": 15
},
{
"page": "Wikipedia:Administrator intervention against vandalism",
"Edits": 15
},
{
"page": "Wikipedia:Vandalismusmeldung",
"Edits": 15
},
{
"page": "The Winds of Winter (Game of Thrones)",
"Edits": 12
},
{
"page": "ولاية الجزائر",
"Edits": 12
},
{
"page": "Copa América",
"Edits": 10
},
{
"page": "Lionel Messi",
"Edits": 10
}
]
延伸阅读
有关使用 Druid SQL 查询的更多信息,请参阅 Druid SQL 文档。
有关 Druid 原生查询的更多信息,请参阅 查询文档。