From a48beac84544ed2db89ac094cc80508742284c1c Mon Sep 17 00:00:00 2001 From: Guy Marriott Date: Mon, 15 Apr 2019 11:36:57 +1200 Subject: [PATCH 1/4] FIX Calculate threshold condition with SQL rather than PHP This is a performance fix. Modern SQL engines can avoid counting a whole result set (potentially thousands of records) when you are only interested if the count exceeds a threshold. --- src/ORM/FieldType/DBForeignKey.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/ORM/FieldType/DBForeignKey.php b/src/ORM/FieldType/DBForeignKey.php index 1c4532204..5071e83e8 100644 --- a/src/ORM/FieldType/DBForeignKey.php +++ b/src/ORM/FieldType/DBForeignKey.php @@ -87,12 +87,27 @@ class DBForeignKey extends DBInt // Add the count of the list to a cache for subsequent calls if (!isset(static::$foreignListCache[$hasOneClass])) { + // Let the DB do the threshold check as it will be faster - depending on the SQL engine it might only have + // to count indexes + $dataQuery = $list->dataQuery()->getFinalisedQuery(); + + // Clear order-by as it's not relevant for counts + $dataQuery->setOrderBy(false); + // Remove distinct. Applying distinct shouldn't be required provided relations are not applied. + $dataQuery->setDistinct(false); + + $dataQuery->setSelect(['over_threshold' => 'count(*) > ' . (int) $threshold]); + $result = $dataQuery->execute()->column('over_threshold'); + $overThreshold = !empty($result) && ($result[0] === 't' || (int) $result[0] === 1); + static::$foreignListCache[$hasOneClass] = [ - 'count' => $list->count(), + 'overThreshold' => $overThreshold, ]; } - if (static::$foreignListCache[$hasOneClass]['count'] < $threshold) { + $overThreshold = static::$foreignListCache[$hasOneClass]['overThreshold']; + + if (!$overThreshold) { // Add the mapped list for the cache if (!isset(static::$foreignListCache[$hasOneClass]['map'])) { static::$foreignListCache[$hasOneClass]['map'] = $list->map('ID', $titleField); From 7fd6e14423dca2f9ff21d90146630f03c3af53bb Mon Sep 17 00:00:00 2001 From: Guy Marriott Date: Tue, 16 Apr 2019 12:10:13 +1200 Subject: [PATCH 2/4] Adding comment about the === 't' condition for supporting postgres --- src/ORM/FieldType/DBForeignKey.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ORM/FieldType/DBForeignKey.php b/src/ORM/FieldType/DBForeignKey.php index 5071e83e8..d8afaab8c 100644 --- a/src/ORM/FieldType/DBForeignKey.php +++ b/src/ORM/FieldType/DBForeignKey.php @@ -98,6 +98,8 @@ class DBForeignKey extends DBInt $dataQuery->setSelect(['over_threshold' => 'count(*) > ' . (int) $threshold]); $result = $dataQuery->execute()->column('over_threshold'); + + // Checking for 't' supports PostgreSQL before silverstripe/postgresql@2.2 $overThreshold = !empty($result) && ($result[0] === 't' || (int) $result[0] === 1); static::$foreignListCache[$hasOneClass] = [ From 80ad336e970c102415d350e92283af4de48bfcf9 Mon Sep 17 00:00:00 2001 From: Guy Marriott Date: Thu, 18 Apr 2019 15:31:41 +1200 Subject: [PATCH 3/4] NEW Add API to create a generator from a DataList (#8931) --- src/ORM/DataList.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/ORM/DataList.php b/src/ORM/DataList.php index 28f538e9f..9110caabb 100644 --- a/src/ORM/DataList.php +++ b/src/ORM/DataList.php @@ -771,6 +771,20 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li return $this; } + /** + * Returns a generator for this DataList + * + * @return \Generator&DataObject[] + */ + public function getGenerator() + { + $query = $this->dataQuery->query()->execute(); + + while ($row = $query->record()) { + yield $this->createDataObject($row); + } + } + public function debug() { $val = "

" . static::class . "

    "; From 86e683c5ecc7919e3958a17aafe406e98bd64914 Mon Sep 17 00:00:00 2001 From: Robbie Averill Date: Sun, 21 Apr 2019 11:09:40 +1200 Subject: [PATCH 4/4] Remove obsolete branch alias --- composer.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/composer.json b/composer.json index 9185afbbd..70628bb75 100644 --- a/composer.json +++ b/composer.json @@ -60,9 +60,6 @@ "psr/container-implementation": "1.0.0" }, "extra": { - "branch-alias": { - "4.x-dev": "4.4.x-dev" - }, "expose": [ "client/images", "client/styles",