# Distributed SQL Operations

__*Distributed SQL*__

+ Distributed `SQL` vs. `TiKV` 

```8
tidb> SELECT ~!@COUNT(*)@!~ FROM universe.planets
   -> WHERE category_id = 1;

tidb> EXPLAIN SELECT COUNT(*) FROM universe.planets WHERE category_id = 1;
+------------------------------+-----------+-----------+---------------+-------------------------------------+
| id                           | estRows   | task      | access object | operator info                       |
+------------------------------+-----------+-----------+---------------+-------------------------------------+
| StreamAgg_20                 | 1.00      | root      |               | funcs:count(Column#27)->Column#25   |
| └─TableReader_21             | 1.00      | root      |               | data:StreamAgg_9                    |
|   └─StreamAgg_9              | 1.00      | ~!@cop[tikv] |               | funcs:count(1)->Column#27@!~           |
|     └─Selection_19           | 163.84    | ~!@cop[tikv] |               | eq(universe.planets.category_id, 1)@!~ |
|       └─TableFullScan_18     | 163840.00 | ~!@cop[tikv] | table:planets | keep order:false, stats:pseudo@!~      |
+------------------------------+-----------+-----------+---------------+-------------------------------------+
5 rows in set (0.00 sec)
```
-------------------------------------------------------------
To keep the compute as close to the storage node as possible to avoid a large number of RPC calls. First, the predicate condition `name = "TiDB"` in SQL should be pushed down to the storage node for computation, so that only valid row are return and meaningless network transfers are avoided. The aggregate function `COUNT(*)` can then also be pushed down to the storage nodes for preaggregation, and each node only needs to return one `COUNT(*)` The results are sufficient, and the results return by each node are `COUNT(*)` summed up by the SQL layer.

