@@ -53,7 +53,7 @@ use crate::{
5353 Statistics ,
5454} ;
5555
56- use arrow:: array:: { Array , RecordBatch , RecordBatchOptions , StringViewArray } ;
56+ use arrow:: array:: { Array , RecordBatch , RecordBatchOptions } ;
5757use arrow:: compute:: { concat_batches, lexsort_to_indices, take_arrays} ;
5858use arrow:: datatypes:: SchemaRef ;
5959use datafusion_common:: config:: SpillCompression ;
@@ -418,8 +418,6 @@ impl ExternalSorter {
418418 Some ( ( self . spill_manager . create_in_progress_file ( "Sorting" ) ?, 0 ) ) ;
419419 }
420420
421- Self :: organize_stringview_arrays ( globally_sorted_batches) ?;
422-
423421 debug ! ( "Spilling sort data of ExternalSorter to disk whilst inserting" ) ;
424422
425423 let batches_to_spill = std:: mem:: take ( globally_sorted_batches) ;
@@ -463,71 +461,6 @@ impl ExternalSorter {
463461 Ok ( ( ) )
464462 }
465463
466- /// Reconstruct `globally_sorted_batches` to organize the payload buffers of each
467- /// `StringViewArray` in sequential order by calling `gc()` on them.
468- ///
469- /// Note this is a workaround until <https://github.com/apache/arrow-rs/issues/7185> is
470- /// available
471- ///
472- /// # Rationale
473- /// After (merge-based) sorting, all batches will be sorted into a single run,
474- /// but physically this sorted run is chunked into many small batches. For
475- /// `StringViewArray`s inside each sorted run, their inner buffers are not
476- /// re-constructed by default, leading to non-sequential payload locations
477- /// (permutated by `interleave()` Arrow kernel). A single payload buffer might
478- /// be shared by multiple `RecordBatch`es.
479- /// When writing each batch to disk, the writer has to write all referenced buffers,
480- /// because they have to be read back one by one to reduce memory usage. This
481- /// causes extra disk reads and writes, and potentially execution failure.
482- ///
483- /// # Example
484- /// Before sorting:
485- /// batch1 -> buffer1
486- /// batch2 -> buffer2
487- ///
488- /// sorted_batch1 -> buffer1
489- /// -> buffer2
490- /// sorted_batch2 -> buffer1
491- /// -> buffer2
492- ///
493- /// Then when spilling each batch, the writer has to write all referenced buffers
494- /// repeatedly.
495- fn organize_stringview_arrays (
496- globally_sorted_batches : & mut Vec < RecordBatch > ,
497- ) -> Result < ( ) > {
498- let mut organized_batches = Vec :: with_capacity ( globally_sorted_batches. len ( ) ) ;
499-
500- for batch in globally_sorted_batches. drain ( ..) {
501- let mut new_columns: Vec < Arc < dyn Array > > =
502- Vec :: with_capacity ( batch. num_columns ( ) ) ;
503-
504- let mut arr_mutated = false ;
505- for array in batch. columns ( ) {
506- if let Some ( string_view_array) =
507- array. as_any ( ) . downcast_ref :: < StringViewArray > ( )
508- {
509- let new_array = string_view_array. gc ( ) ;
510- new_columns. push ( Arc :: new ( new_array) ) ;
511- arr_mutated = true ;
512- } else {
513- new_columns. push ( Arc :: clone ( array) ) ;
514- }
515- }
516-
517- let organized_batch = if arr_mutated {
518- RecordBatch :: try_new ( batch. schema ( ) , new_columns) ?
519- } else {
520- batch
521- } ;
522-
523- organized_batches. push ( organized_batch) ;
524- }
525-
526- * globally_sorted_batches = organized_batches;
527-
528- Ok ( ( ) )
529- }
530-
531464 /// Sorts the in-memory batches and merges them into a single sorted run, then writes
532465 /// the result to spill files.
533466 async fn sort_and_spill_in_mem_batches ( & mut self ) -> Result < ( ) > {
0 commit comments