Repository: dask/dask
Issue category: Performance Issue

Slicing an Array with full slices along every dimension should just map the keys
```
ds = xr.open_zarr(
    "gs://weatherbench2/datasets/era5/1959-2023_01_10-wb13-6h-1440x721.zarr",
    #consolidated=True
)
ds = ds[variables].sel(time=slice("2020-01-01", "2022-12-31"))
```

The dataset has one point per chunk along the time axis, so every slice is trivial

<img width="634" alt="Screenshot 2024-10-18 at 17 09 25" src="https://github.com/user-attachments/assets/2c005e78-d97b-4e67-9936-c63ca54a7b66">

this creates a lot of tasks that look like this:

```
 ('getitem-cbd92e9090b2dd038943d6de9184aefe',
  1,
  0,
  0): (<function dask.array.chunk.getitem(obj, index)>, ('open_dataset-sea_surface_temperature-c20638560e986ac27140dafa0e57ac52',
   89121,
   0,
   0), (slice(None, None, None),
   slice(None, None, None),
   slice(None, None, None))),
```

We should optimise this away to something like:

```
 ('getitem-cbd92e9090b2dd038943d6de9184aefe',
  1,
  0,
  0): ('open_dataset-sea_surface_temperature-c20638560e986ac27140dafa0e57ac52',
   89121,
   0,
   0),
```


Functions to edit:
dask/array/slicing.py:slice_with_newaxes
dask/array/slicing.py:slice_wrap_lists
dask/array/slicing.py:slice_slices_and_integers

Patch:
diff --git a/dask/array/slicing.py b/dask/array/slicing.py
index c18e529392c..ec12479cf99 100644
--- a/dask/array/slicing.py
+++ b/dask/array/slicing.py
@@ -195,7 +195,9 @@ def slice_with_newaxes(out_name, in_name, blockdims, index):
             where_none[i] -= n
 
     # Pass down and do work
-    dsk, blockdims2 = slice_wrap_lists(out_name, in_name, blockdims, index2)
+    dsk, blockdims2 = slice_wrap_lists(
+        out_name, in_name, blockdims, index2, not where_none
+    )
 
     if where_none:
         expand = expander(where_none)
@@ -220,7 +222,7 @@ def slice_with_newaxes(out_name, in_name, blockdims, index):
         return dsk, blockdims2
 
 
-def slice_wrap_lists(out_name, in_name, blockdims, index):
+def slice_wrap_lists(out_name, in_name, blockdims, index, allow_getitem_optimization):
     """
     Fancy indexing along blocked array dasks
 
@@ -251,7 +253,9 @@ def slice_wrap_lists(out_name, in_name, blockdims, index):
 
     # No lists, hooray! just use slice_slices_and_integers
     if not where_list:
-        return slice_slices_and_integers(out_name, in_name, blockdims, index)
+        return slice_slices_and_integers(
+            out_name, in_name, blockdims, index, allow_getitem_optimization
+        )
 
     # Replace all lists with full slices  [3, 1, 0] -> slice(None, None, None)
     index_without_list = tuple(
@@ -269,7 +273,11 @@ def slice_wrap_lists(out_name, in_name, blockdims, index):
         # Do first pass without lists
         tmp = "slice-" + tokenize((out_name, in_name, blockdims, index))
         dsk, blockdims2 = slice_slices_and_integers(
-            tmp, in_name, blockdims, index_without_list
+            tmp,
+            in_name,
+            blockdims,
+            index_without_list,
+            allow_getitem_optimization=False,
         )
 
         # After collapsing some axes due to int indices, adjust axis parameter
@@ -285,7 +293,9 @@ def slice_wrap_lists(out_name, in_name, blockdims, index):
     return dsk3, blockdims2
 
 
-def slice_slices_and_integers(out_name, in_name, blockdims, index):
+def slice_slices_and_integers(
+    out_name, in_name, blockdims, index, allow_getitem_optimization=False
+):
     """
     Dask array indexing with slices and integers
 
@@ -329,7 +339,12 @@ def slice_slices_and_integers(out_name, in_name, blockdims, index):
     all_slices = list(product(*[pluck(1, s) for s in sorted_block_slices]))
 
     dsk_out = {
-        out_name: (getitem, in_name, slices)
+        out_name: (
+            (getitem, in_name, slices)
+            if not allow_getitem_optimization
+            or not all(sl == slice(None, None, None) for sl in slices)
+            else in_name
+        )
         for out_name, in_name, slices in zip(out_names, in_names, all_slices)
     }
 

Test patch: diff --git a/dask/array/tests/test_slicing.py b/dask/array/tests/test_slicing.py
index a5ea273707f..2d1ab3006c8 100644
--- a/dask/array/tests/test_slicing.py
+++ b/dask/array/tests/test_slicing.py
@@ -1036,3 +1036,13 @@ def test_take_sorted_indexer():
             )
         },
     } == dict(result.dask)
+
+
+def test_all_none_slices_just_mappings():
+    arr = da.ones((10, 10), chunks=(1, 5))
+    result = arr[slice(None, 6), slice(None)]
+    dsk = dict(result.dask)
+    assert len([k for k in dsk if "getitem" in k[0]]) == 12
+    # check that we are just mapping the keys
+    assert all(v in dsk for k, v in dsk.items() if "getitem" in k[0])
+    assert_eq(result, np.ones((6, 10)))