[11.x] PDO modes on query builder #50307
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
PDO modes
This PR adds the ability for developers to customize the underlying PDO mode for a query. Particularly, this is beneficial for certain queries like
pluck()
since they can be retrieved more efficiently using a specific PDO fetch mode.The gist of this PR is the addition of the
$query->mode()
function which can be called with a set of predefined modes that changes PDO settings just before executing/fetching the$statement
in the Connection class.Features
Improved
$query->pluck()
Faster
$query->pluck()
retrieval (see benchmarks below) by utilizing the PDO::FETCH_KEY_PAIR mode (now built into the pluck function). The end-result of the pluck function remains unchanged and the original pluck behavior has already been added to the tests in #48657.Additionally, raw DB statements can now be added for the
$key
parameter as well.Added
$query->mode(DB::mode()->keyed())
The "keyed" mode consumes the first column of the result and uses it as the key for the returned collection. It can be set using
$query->mode(DB::mode()->keyed())
on a query builder. Rows with duplicate keys will overwrite the previous entry, just as the$collection->keyBy('...')
function.This provides a nice optimization (see benchmarks below) for cases where you previously would have called
User::query()->get()->keyBy('...')
(retrieving a query, after which the collection is looped and keyed using PHP). Now, the result is keyed as it comes back from PDO which saves a complete processing loop.Added
$query->mode(DB::mode()->buffered(false))
The "buffered" mode changes the buffer setting (only applicable to MySQL) which may provide memory optimizations for processing large datasets using a cursor.
Added
$query->mode(DB::mode()->scrollableCursor($nth))
The "scrollableCursor" mode changes how the cursor runs and skips through the result set. For instance, providing the parameter
$nth = 2
takes only every second result from the cursor. This functionality is only available on Postgres and MS SQL.Notable changes
src/Illuminate/Database/PDO/Mode.php
which has common PDO modes for the developer to use.src/Illuminate/Database/PDO/Statement.php
which is a wrapper around PDO Statement. (it is purposively not extended since that may introduce difficulties when providing support for different PHP versions).src/Illuminate/Database/ConnectionInterface.php
namely the addition of the new$mode
:public function select($query, $bindings = [], $useReadPdo = true, Mode $mode = null);
public function cursor($query, $bindings = [], $useReadPdo = true, Mode $mode = null);
src/Illuminate/Database/Query/Builder.php
:protected function onceWithColumns()
and used$this->clone()
in those cases where it was used, to simplify and flattten the function.public function pluck()
to use the new modestripTableForPluck()
,pluckFromObjectColumn()
andpluckFromArrayColumn()
since those functions are no longer necessary forpluck()
. The pluck result is now always returned as['key' => 'value']
(no longer in object format), so no further parsing is needed.tests
to fix theselect()
function mock, since a new (optional) parameter was added which was no longer recognized by mockery (even though it is an optional parameter).Benchmarks
Benchmark (gist) of 1000 iterations on various amounts of rows: