#apache-spark #apache-spark-sql
#apache-spark #apache-spark-sql
Вопрос:
spark-sql Я использую Spark-sql 2.4.
У меня есть вопрос, который не дает мне покоя уже довольно давно — использовать ли DISTINCT
OR GROUP BY
(без каких-либо агрегаций) для эффективного удаления дубликатов из таблицы с лучшей производительностью запросов.
При DISTINCT
этом я бы использовал следующее —
select distinct
id,
fname,
lname,
age
from emp_table;
Для GROUP BY
я просто использую :
select id,
fname,
lname,
age
from emp_table
group by 1, 2, 3, 4;
Я где-то читал о Spark-SQL
том, что это Distinct
следует использовать, только если значение cardinality
набора данных велико, в противном случае используйте Group By
. Однако в моей повседневной работе я видел, что Duplicate
это работает лучше, чем Group By
даже в сценариях, где мощность низкая.
Итак, мой вопрос в том, какой из них будет работать лучше в каких сценариях.
Может кто-нибудь, пожалуйста, просветите меня по этому вопросу. В каких условиях запрос с будет выполняться лучше, чем в каких сценариях. Distinct
Group By
Спасибо
Комментарии:
1. попробуйте .explain и расскажите нам о своих выводах.
Ответ №1:
Они функционально эквивалентны и будут генерировать один и тот же план запроса. Для наглядности используйте distinct.
Ответ №2:
Вот планы запросов для двух запросов. Как сказал @thebluephantom, они идентичны, поэтому не должно быть никакой разницы в производительности.
create table t1 (a int, b int, c int, d int);
explain select a,b,c,d from t1 group by 1,2,3,4;
== Physical Plan ==
*(2) HashAggregate(keys=[a#14, b#15, c#16, d#17], functions=[])
- Exchange hashpartitioning(a#14, b#15, c#16, d#17, 200), true, [id=#33]
- *(1) HashAggregate(keys=[a#14, b#15, c#16, d#17], functions=[])
- Scan hive default.t1 [a#14, b#15, c#16, d#17], HiveTableRelation `default`.`t1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [a#14, b#15, c#16, d#17], Statistics(sizeInBytes=8.0 EiB)
explain select distinct a,b,c,d from t1;
== Physical Plan ==
*(2) HashAggregate(keys=[a#23, b#24, c#25, d#26], functions=[])
- Exchange hashpartitioning(a#23, b#24, c#25, d#26, 200), true, [id=#58]
- *(1) HashAggregate(keys=[a#23, b#24, c#25, d#26], functions=[])
- Scan hive default.t1 [a#23, b#24, c#25, d#26], HiveTableRelation `default`.`t1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [a#23, b#24, c#25, d#26], Statistics(sizeInBytes=8.0 EiB)
Расширенное объяснение показывает, что запрос стал идентичным после их оптимизации:
explain extended select a,b,c,d from t1 group by 1,2,3,4;
== Parsed Logical Plan ==
'Aggregate [1, 2, 3, 4], ['a, 'b, 'c, 'd]
- 'UnresolvedRelation [t1]
== Analyzed Logical Plan ==
a: int, b: int, c: int, d: int
Aggregate [a#41, b#42, c#43, d#44], [a#41, b#42, c#43, d#44]
- SubqueryAlias spark_catalog.default.t1
- HiveTableRelation `default`.`t1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [a#41, b#42, c#43, d#44], Statistics(sizeInBytes=8.0 EiB)
== Optimized Logical Plan ==
Aggregate [a#41, b#42, c#43, d#44], [a#41, b#42, c#43, d#44]
- HiveTableRelation `default`.`t1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [a#41, b#42, c#43, d#44], Statistics(sizeInBytes=8.0 EiB)
== Physical Plan ==
*(2) HashAggregate(keys=[a#41, b#42, c#43, d#44], functions=[], output=[a#41, b#42, c#43, d#44])
- Exchange hashpartitioning(a#41, b#42, c#43, d#44, 200), true, [id=#108]
- *(1) HashAggregate(keys=[a#41, b#42, c#43, d#44], functions=[], output=[a#41, b#42, c#43, d#44])
- Scan hive default.t1 [a#41, b#42, c#43, d#44], HiveTableRelation `default`.`t1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [a#41, b#42, c#43, d#44], Statistics(sizeInBytes=8.0 EiB)
explain extended select distinct a,b,c,d from t1;
== Parsed Logical Plan ==
'Distinct
- 'Project ['a, 'b, 'c, 'd]
- 'UnresolvedRelation [t1]
== Analyzed Logical Plan ==
a: int, b: int, c: int, d: int
Distinct
- Project [a#50, b#51, c#52, d#53]
- SubqueryAlias spark_catalog.default.t1
- HiveTableRelation `default`.`t1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [a#50, b#51, c#52, d#53], Statistics(sizeInBytes=8.0 EiB)
== Optimized Logical Plan ==
Aggregate [a#50, b#51, c#52, d#53], [a#50, b#51, c#52, d#53]
- HiveTableRelation `default`.`t1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [a#50, b#51, c#52, d#53], Statistics(sizeInBytes=8.0 EiB)
== Physical Plan ==
*(2) HashAggregate(keys=[a#50, b#51, c#52, d#53], functions=[], output=[a#50, b#51, c#52, d#53])
- Exchange hashpartitioning(a#50, b#51, c#52, d#53, 200), true, [id=#133]
- *(1) HashAggregate(keys=[a#50, b#51, c#52, d#53], functions=[], output=[a#50, b#51, c#52, d#53])
- Scan hive default.t1 [a#50, b#51, c#52, d#53], HiveTableRelation `default`.`t1`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [a#50, b#51, c#52, d#53], Statistics(sizeInBytes=8.0 EiB)
И на самом деле предполагает, что механизм запросов, похоже, предпочитает group by
запрос.
Комментарии:
1. спасибо за ваш ответ. Можете ли вы, пожалуйста, помочь мне понять, почему вы говорите, что
group by
это предложение предпочтительнее на основе приведенных выше планов запросов.2. @Matthew извините, если я плохо сформулировал это, я просто имел в виду, что оптимизированный запрос больше похож на неоптимизированный запрос group by, чем на неоптимизированный запрос distinct. Это просто наблюдение, которое не имеет отношения к тому, как на самом деле выполняется запрос. Я бы предложил использовать distinct в вашем реальном запросе для повышения удобства чтения.
3. @thebluephantom не совсем, мне просто интересно это понять — это действительно первый раз, когда я запускаю
explain extended
4. нет, я имею в виду вообще? у вас стремительный рост, просто интересно…