diff --git a/typo3/sysext/backend/Classes/Controller/BackendController.php b/typo3/sysext/backend/Classes/Controller/BackendController.php
index 40d76e2350b9caf900037c1975e345ebe7d224ad..bff93714611c90fb1028e5f0be85b944398b1bbf 100644
--- a/typo3/sysext/backend/Classes/Controller/BackendController.php
+++ b/typo3/sysext/backend/Classes/Controller/BackendController.php
@@ -20,8 +20,12 @@ use TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository;
 use TYPO3\CMS\Backend\Module\ModuleLoader;
 use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
+use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Page\PageRenderer;
+use TYPO3\CMS\Core\Type\Bitmask\Permission;
 use TYPO3\CMS\Core\Type\File\ImageInfo;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -720,16 +724,35 @@ class BackendController
         $beUser = $this->getBackendUser();
         // EDIT page:
         $editId = preg_replace('/[^[:alnum:]_]/', '', GeneralUtility::_GET('edit'));
-        $editRecord = '';
         if ($editId) {
             // Looking up the page to edit, checking permissions:
             $where = ' AND (' . $beUser->getPagePermsClause(2) . ' OR ' . $beUser->getPagePermsClause(16) . ')';
             if (MathUtility::canBeInterpretedAsInteger($editId)) {
                 $editRecord = BackendUtility::getRecordWSOL('pages', $editId, '*', $where);
             } else {
-                $records = BackendUtility::getRecordsByField('pages', 'alias', $editId, $where);
-                if (is_array($records)) {
-                    $editRecord = reset($records);
+                $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
+                $queryBuilder->getRestrictions()
+                    ->removeAll()
+                    ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+                    ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+                $editRecord = $queryBuilder->select('*')
+                    ->from('pages')
+                    ->where(
+                        $queryBuilder->expr()->eq(
+                            'alias',
+                            $queryBuilder->createNamedParameter($editId, \PDO::PARAM_STR)
+                        ),
+                        $queryBuilder->expr()->orX(
+                            $beUser->getPagePermsClause(Permission::PAGE_EDIT),
+                            $beUser->getPagePermsClause(Permission::CONTENT_EDIT)
+                        )
+                    )
+                    ->setMaxResults(1)
+                    ->execute()
+                    ->fetch();
+
+                if ($editRecord !== false) {
                     BackendUtility::workspaceOL('pages', $editRecord);
                 }
             }
diff --git a/typo3/sysext/backend/Classes/Domain/Repository/Localization/LocalizationRepository.php b/typo3/sysext/backend/Classes/Domain/Repository/Localization/LocalizationRepository.php
index 10b16e762db481ac990778076caf717d488c1521..dba66f8c464186224e890ebf1296a9c28ed01e41 100644
--- a/typo3/sysext/backend/Classes/Domain/Repository/Localization/LocalizationRepository.php
+++ b/typo3/sysext/backend/Classes/Domain/Repository/Localization/LocalizationRepository.php
@@ -18,6 +18,7 @@ use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
+use TYPO3\CMS\Core\Database\Query\QueryHelper;
 use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -330,15 +331,32 @@ class LocalizationRepository
             $tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
 
             if (isset($tcaCtrl['origUid'])) {
-                $recordLocalization = BackendUtility::getRecordsByField(
-                    $table,
-                    $tcaCtrl['origUid'],
-                    $uid,
-                    'AND ' . $tcaCtrl['languageField'] . '=' . (int)$language . ($andWhereClause ? ' ' . $andWhereClause : ''),
-                    '',
-                    '',
-                    '1'
-                );
+                $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+                    ->getQueryBuilderForTable($table);
+                $queryBuilder->getRestrictions()
+                    ->removeAll()
+                    ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+                    ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+                $queryBuilder->select('*')
+                    ->from($table)
+                    ->where(
+                        $queryBuilder->expr()->eq(
+                            $tcaCtrl['origUid'],
+                            $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
+                        ),
+                        $queryBuilder->expr()->eq(
+                            $tcaCtrl['languageField'],
+                            $queryBuilder->createNamedParameter((int)$language, \PDO::PARAM_INT)
+                        )
+                    )
+                    ->setMaxResults(1);
+
+                if ($andWhereClause) {
+                    $queryBuilder->andWhere(QueryHelper::stripLogicalOperatorPrefix($andWhereClause));
+                }
+
+                $recordLocalization = $queryBuilder->execute()->fetchAll();
             }
         }
         return $recordLocalization;
diff --git a/typo3/sysext/backend/Classes/Utility/BackendUtility.php b/typo3/sysext/backend/Classes/Utility/BackendUtility.php
index 3d30e6867e3f43c937df9f79dbb6364728799038..7308eda5aec6ce7e24e0277b2584eae792961b20 100644
--- a/typo3/sysext/backend/Classes/Utility/BackendUtility.php
+++ b/typo3/sysext/backend/Classes/Utility/BackendUtility.php
@@ -221,6 +221,7 @@ class BackendUtility
      * @param bool $useDeleteClause Use the deleteClause to check if a record is deleted (default TRUE)
      * @param null|QueryBuilder $queryBuilder The queryBuilder must be provided, if the parameter $whereClause is given and the concept of prepared statement was used. Example within self::firstDomainRecord()
      * @return mixed Multidimensional array with selected records (if any is selected)
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9
      */
     public static function getRecordsByField(
         $theTable,
@@ -233,6 +234,7 @@ class BackendUtility
         $useDeleteClause = true,
         $queryBuilder = null
     ) {
+        GeneralUtility::logDeprecatedFunction();
         if (is_array($GLOBALS['TCA'][$theTable])) {
             if (null === $queryBuilder) {
                 $queryBuilder = static::getQueryBuilderForTable($theTable);
@@ -394,27 +396,32 @@ class BackendUtility
 
             $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
                 ->getQueryBuilderForTable($table);
+            $queryBuilder->getRestrictions()
+                ->removeAll()
+                ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+                ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
 
-            $constraint = $queryBuilder->expr()->andX(
-                $queryBuilder->expr()->eq(
-                    $tcaCtrl['languageField'],
-                    $queryBuilder->createNamedParameter($language, \PDO::PARAM_INT)
-                ),
-                QueryHelper::stripLogicalOperatorPrefix($andWhereClause)
-            );
+            $queryBuilder->select('*')
+                ->from($table)
+                ->where(
+                    $queryBuilder->expr()->eq(
+                        $tcaCtrl['transOrigPointerField'],
+                        $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
+                    ),
+                    $queryBuilder->expr()->eq(
+                        $tcaCtrl['languageField'],
+                        $queryBuilder->createNamedParameter((int)$language, \PDO::PARAM_INT)
+                    )
+                )
+                ->setMaxResults(1);
 
-            $recordLocalization = self::getRecordsByField(
-                $table,
-                $tcaCtrl['transOrigPointerField'],
-                $uid,
-                (string)$constraint,
-                '',
-                '',
-                1,
-                true,
-                $queryBuilder
-            );
+            if ($andWhereClause) {
+                $queryBuilder->andWhere(QueryHelper::stripLogicalOperatorPrefix($andWhereClause));
+            }
+
+            $recordLocalization = $queryBuilder->execute()->fetchAll();
         }
+
         return $recordLocalization;
     }
 
@@ -3970,31 +3977,37 @@ class BackendUtility
     public static function firstDomainRecord($rootLine)
     {
         $queryBuilder = static::getQueryBuilderForTable('sys_domain');
-        $constraint = $queryBuilder->expr()->andX(
-            $queryBuilder->expr()->eq(
-                'redirectTo',
-                $queryBuilder->createNamedParameter('', \PDO::PARAM_STR)
-            ),
-            $queryBuilder->expr()->eq(
-                'hidden',
-                $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
+        $queryBuilder->getRestrictions()
+            ->removeAll()
+            ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+            ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+        $queryBuilder->select('domainName')
+            ->from('sys_domain')
+            ->where(
+                $queryBuilder->expr()->eq(
+                    'pid',
+                    $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT, ':pid')
+                ),
+                $queryBuilder->expr()->eq(
+                    'redirectTo',
+                    $queryBuilder->createNamedParameter('', \PDO::PARAM_STR)
+                ),
+                $queryBuilder->expr()->eq(
+                    'hidden',
+                    $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
+                )
             )
-        );
+            ->setMaxResults(1)
+            ->orderBy('sorting');
+
         foreach ($rootLine as $row) {
-            $dRec = self::getRecordsByField(
-                'sys_domain',
-                'pid',
-                $row['uid'],
-                (string)$constraint,
-                '',
-                'sorting',
-                '',
-                true,
-                $queryBuilder
-            );
-            if (is_array($dRec)) {
-                $dRecord = reset($dRec);
-                return rtrim($dRecord['domainName'], '/');
+            $domainName = $queryBuilder->setParameter('pid', $row['uid'], \PDO::PARAM_INT)
+                ->execute()
+                ->fetchColumn(0);
+
+            if ($domainName) {
+                return rtrim($domainName, '/');
             }
         }
         return null;
diff --git a/typo3/sysext/backend/Classes/View/PageLayoutView.php b/typo3/sysext/backend/Classes/View/PageLayoutView.php
index 09951be563a17f2797eeee00922902d13a20d598..19fd03f16ce136e7a07cb7e4032e3b92e10705d1 100644
--- a/typo3/sysext/backend/Classes/View/PageLayoutView.php
+++ b/typo3/sysext/backend/Classes/View/PageLayoutView.php
@@ -453,28 +453,32 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
             $userCanEditPage = $this->getBackendUser()->check('tables_modify', 'pages_language_overlay');
         }
         if ($userCanEditPage) {
-            $languageOverlayId = 0;
             $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
-                ->getConnectionForTable('pages_language_overlay')
-                ->createQueryBuilder();
-            $constraint = $queryBuilder->expr()->eq(
-                'sys_language_uid',
-                $queryBuilder->createNamedParameter($this->tt_contentConfig['sys_language_uid'], \PDO::PARAM_INT)
-            );
-            $pageOverlayRecord = BackendUtility::getRecordsByField(
-                'pages_language_overlay',
-                'pid',
-                (int)$this->id,
-                $constraint,
-                '',
-                '',
-                '',
-                true,
-                $queryBuilder
-            );
-            if (!empty($pageOverlayRecord[0]['uid'])) {
-                $languageOverlayId = $pageOverlayRecord[0]['uid'];
-            }
+                ->getQueryBuilderForTable('pages_language_overlay');
+            $queryBuilder->getRestrictions()
+                ->removeAll()
+                ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+                ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+            $queryBuilder->select('uid')
+                ->from('pages_language_overlay')
+                ->where(
+                    $queryBuilder->expr()->eq(
+                        'pid',
+                        $queryBuilder->createNamedParameter((int)$this->id, \PDO::PARAM_INT)
+                    ),
+                    $queryBuilder->expr()->eq(
+                        'sys_language_uid',
+                        $queryBuilder->createNamedParameter(
+                            $this->tt_contentConfig['sys_language_uid'],
+                            \PDO::PARAM_INT
+                        )
+                    )
+                )
+                ->setMaxResults(1);
+
+            $languageOverlayId = (int)$queryBuilder->execute()->fetchColumn(0);
+
             $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/PageActions', 'function(PageActions) {
                 PageActions.setPageId(' . (int)$this->id . ');
                 PageActions.setLanguageOverlayId(' . $languageOverlayId . ');
@@ -853,7 +857,29 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                 }
                 // Language overlay page header:
                 if ($lP) {
-                    list($lpRecord) = BackendUtility::getRecordsByField('pages_language_overlay', 'pid', $id, 'AND sys_language_uid=' . $lP);
+                    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+                        ->getQueryBuilderForTable('pages_language_overlay');
+                    $queryBuilder->getRestrictions()
+                        ->removeAll()
+                        ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+                        ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+                    $lpRecord = $queryBuilder->select('*')
+                        ->from('pages_language_overlay')
+                        ->where(
+                            $queryBuilder->expr()->eq(
+                                'pid',
+                                $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)
+                            ),
+                            $queryBuilder->expr()->eq(
+                                'sys_language_uid',
+                                $queryBuilder->createNamedParameter($lP, \PDO::PARAM_INT)
+                            )
+                        )
+                        ->setMaxResults(1)
+                        ->execute()
+                        ->fetch();
+
                     BackendUtility::workspaceOL('pages_language_overlay', $lpRecord);
                     $recordIcon = BackendUtility::wrapClickMenuOnIcon(
                         $this->iconFactory->getIconForRecord('pages_language_overlay', $lpRecord, Icon::SIZE_SMALL)->render(),
diff --git a/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php b/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6d0b903dc1cf84ebbcb7d7b563247c58be3b371f
--- /dev/null
+++ b/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php
@@ -0,0 +1,48 @@
+<?php
+namespace TYPO3\CMS\Backend\Tests\Functional\Controller\Page;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\RootlineUtility;
+
+/**
+ * Test case for TYPO3\CMS\Backend\Controller\Page\LocalizationController
+ */
+class BackendUtilityTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
+{
+    /**
+     * Sets up this test case.
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        parent::setUp();
+
+        $this->importDataSet(ORIGINAL_ROOT . 'components/testing_framework/Resources/Core/Functional/Fixtures/pages.xml');
+        $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/backend/Tests/Functional/Utility/Fixtures/sys_domain.xml');
+    }
+
+    /**
+     * @test
+     */
+    public function determineFirstDomainRecord()
+    {
+        $rootLineUtility = GeneralUtility::makeInstance(RootlineUtility::class, 4);
+        $rootLine = $rootLineUtility->get();
+        $this->assertEquals('example.com', BackendUtility::firstDomainRecord($rootLine));
+    }
+}
diff --git a/typo3/sysext/backend/Tests/Functional/Utility/Fixtures/sys_domain.xml b/typo3/sysext/backend/Tests/Functional/Utility/Fixtures/sys_domain.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba49fcfd0ab283ddc184286be82ce3c4dff76908
--- /dev/null
+++ b/typo3/sysext/backend/Tests/Functional/Utility/Fixtures/sys_domain.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<dataset>
+    <sys_domain>
+        <uid>1</uid>
+        <pid>1</pid>
+        <tstamp>1487563944</tstamp>
+        <hidden>0</hidden>
+        <domainName>example.com</domainName>
+        <forced>1</forced>
+    </sys_domain>
+    <sys_domain>
+        <uid>2</uid>
+        <pid>7</pid>
+        <tstamp>1487563945</tstamp>
+        <hidden>0</hidden>
+        <domainName>www.example.net</domainName>
+        <redirectTo>http://example.com/</redirectTo>
+        <redirectHttpStatusCode>301</redirectHttpStatusCode>
+        <forced>0</forced>
+    </sys_domain>
+</dataset>
diff --git a/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php b/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php
index b7c888764b5962b2b90c2a02523a7d7d34039120..b977620ae09a2225a29964ed04b0025f218b2682 100644
--- a/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php
+++ b/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php
@@ -19,6 +19,7 @@ use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
 use TYPO3\CMS\Core\Database\Query\QueryHelper;
+use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
 use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
 use TYPO3\CMS\Core\Database\Query\Restriction\RootLevelRestriction;
@@ -701,15 +702,30 @@ class BackendUserAuthentication extends \TYPO3\CMS\Core\Authentication\AbstractU
                 $pointerField = $GLOBALS['TCA'][$l10nTable]['ctrl']['transOrigPointerField'];
                 $pointerValue = $record[$pointerField] > 0 ? $record[$pointerField] : $record['uid'];
             }
-            $recordLocalizations = BackendUtility::getRecordsByField($l10nTable, $pointerField, $pointerValue, '', '', '', '1');
-            if (is_array($recordLocalizations)) {
-                foreach ($recordLocalizations as $localization) {
-                    $recordLocalizationAccess = $recordLocalizationAccess
-                        && $this->checkLanguageAccess($localization[$GLOBALS['TCA'][$l10nTable]['ctrl']['languageField']]);
-                    if (!$recordLocalizationAccess) {
-                        break;
-                    }
-                }
+
+            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($l10nTable);
+            $queryBuilder->getRestrictions()
+                ->removeAll()
+                ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+                ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+            $recordLocalization = $queryBuilder->select('*')
+                ->from($l10nTable)
+                ->where(
+                    $queryBuilder->expr()->eq(
+                        $pointerField,
+                        $queryBuilder->createNamedParameter($pointerValue, \PDO::PARAM_INT)
+                    )
+                )
+                ->setMaxResults(1)
+                ->execute()
+                ->fetch();
+
+            if (is_array($recordLocalization)) {
+                $languageAccess = $this->checkLanguageAccess(
+                    $recordLocalization[$GLOBALS['TCA'][$l10nTable]['ctrl']['languageField']]
+                );
+                $recordLocalizationAccess = $recordLocalizationAccess && $languageAccess;
             }
         }
         return $recordLocalizationAccess;
diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php
index 7e2f10283c52e635afd380974b162a70840c2cfb..3ae0c18b078896dd612ccac67d210ca89fbf0df8 100644
--- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php
+++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php
@@ -27,6 +27,7 @@ use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
 use TYPO3\CMS\Core\Database\Query\QueryHelper;
+use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
 use TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionContainerInterface;
 use TYPO3\CMS\Core\Database\ReferenceIndex;
@@ -2630,12 +2631,44 @@ class DataHandler
     public function getRecordsWithSameValue($tableName, $uid, $fieldName, $value, $pageId = 0)
     {
         $result = [];
-        if (!empty($GLOBALS['TCA'][$tableName]['columns'][$fieldName])) {
-            $uid = (int)$uid;
-            $pageId = (int)$pageId;
-            $whereStatement = ' AND uid <> ' . $uid . ' AND ' . ($pageId ? 'pid = ' . $pageId : 'pid >= 0');
-            $result = BackendUtility::getRecordsByField($tableName, $fieldName, $value, $whereStatement);
+        if (empty($GLOBALS['TCA'][$tableName]['columns'][$fieldName])) {
+            return $result;
         }
+
+        $uid = (int)$uid;
+        $pageId = (int)$pageId;
+
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($tableName);
+        $queryBuilder->getRestrictions()
+            ->removeAll()
+            ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+            ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+        $queryBuilder->select('*')
+            ->from($tableName)
+            ->where(
+                $queryBuilder->expr()->eq(
+                    $fieldName,
+                    $queryBuilder->createNamedParameter($value, \PDO::PARAM_STR)
+                ),
+                $queryBuilder->expr()->neq(
+                    'uid',
+                    $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
+                )
+            );
+
+        if ($pageId) {
+            $queryBuilder->andWhere(
+                $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT))
+            );
+        } else {
+            $queryBuilder->andWhere(
+                $queryBuilder->expr()->gte('pid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
+            );
+        }
+
+        $result = $queryBuilder->execute()->fetchAll();
+
         return $result;
     }
 
@@ -4112,20 +4145,38 @@ class DataHandler
         if (!BackendUtility::isTableLocalizable($table) ||  $table === 'pages' || $table === 'pages_language_overlay') {
             return;
         }
-        $where = '';
+
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
+        $queryBuilder->getRestrictions()
+            ->removeAll()
+            ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+            ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+        $queryBuilder->select('*')
+            ->from($table)
+            ->where(
+                $queryBuilder->expr()->eq(
+                    $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'],
+                    $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT, ':pointer')
+                )
+            );
+
         if (isset($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) && $GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
-            $where = ' AND t3ver_oid=0';
+            $queryBuilder->andWhere(
+                $queryBuilder->expr()->eq('t3ver_oid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
+            );
         }
         // If $destPid is < 0, get the pid of the record with uid equal to abs($destPid)
         $tscPID = BackendUtility::getTSconfig_pidValue($table, $uid, $destPid);
         // Get the localized records to be copied
-        $l10nRecords = BackendUtility::getRecordsByField($table, $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'], $uid, $where);
+        $l10nRecords = $queryBuilder->execute()->fetchAll();
         if (is_array($l10nRecords)) {
             $localizedDestPids = [];
             // If $destPid < 0, then it is the uid of the original language record we are inserting after
             if ($destPid < 0) {
                 // Get the localized records of the record we are inserting after
-                $destL10nRecords = BackendUtility::getRecordsByField($table, $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'], abs($destPid), $where);
+                $queryBuilder->setParameter('pointer', abs($destPid), \PDO::PARAM_INT);
+                $destL10nRecords = $queryBuilder->execute()->fetchAll();
                 // Index the localized record uids by language
                 if (is_array($destL10nRecords)) {
                     foreach ($destL10nRecords as $record) {
@@ -4512,17 +4563,36 @@ class DataHandler
         if (!BackendUtility::isTableLocalizable($table) || $table === 'pages' || $table === 'pages_language_overlay') {
             return;
         }
-        $where = '';
+
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
+        $queryBuilder->getRestrictions()
+            ->removeAll()
+            ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+            ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+        $queryBuilder->select('*')
+            ->from($table)
+            ->where(
+                $queryBuilder->expr()->eq(
+                    $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'],
+                    $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT, ':pointer')
+                )
+            );
+
         if (isset($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) && $GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
-            $where = ' AND t3ver_oid=0';
+            $queryBuilder->andWhere(
+                $queryBuilder->expr()->eq('t3ver_oid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
+            );
         }
-        $l10nRecords = BackendUtility::getRecordsByField($table, $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'], $uid, $where);
+
+        $l10nRecords = $queryBuilder->execute()->fetchAll();
         if (is_array($l10nRecords)) {
             $localizedDestPids = [];
             // If $$originalRecordDestinationPid < 0, then it is the uid of the original language record we are inserting after
             if ($originalRecordDestinationPid < 0) {
                 // Get the localized records of the record we are inserting after
-                $destL10nRecords = BackendUtility::getRecordsByField($table, $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'], abs($originalRecordDestinationPid), $where);
+                $queryBuilder->setParameter('pointer', abs($originalRecordDestinationPid), \PDO::PARAM_INT);
+                $destL10nRecords = $queryBuilder->execute()->fetchAll();
                 // Index the localized record uids by language
                 if (is_array($destL10nRecords)) {
                     foreach ($destL10nRecords as $record) {
@@ -4620,10 +4690,32 @@ class DataHandler
         }
 
         if ($table === 'pages') {
-            $pass = !BackendUtility::getRecordsByField('pages_language_overlay', 'pid', $uid, (' AND ' . $GLOBALS['TCA']['pages_language_overlay']['ctrl']['languageField'] . '=' . (int)$langRec['uid']));
+            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+                ->getQueryBuilderForTable('pages_language_overlay');
+            $queryBuilder->getRestrictions()
+                ->removeAll()
+                ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+                ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+            $recordCount = $queryBuilder->count('*')
+                ->from('pages_language_overlay')
+                ->where(
+                    $queryBuilder->expr()->eq(
+                        'pid',
+                        $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
+                    ),
+                    $queryBuilder->expr()->eq(
+                        $GLOBALS['TCA']['pages_language_overlay']['ctrl']['languageField'],
+                        $queryBuilder->createNamedParameter((int)$langRec['uid'], \PDO::PARAM_INT)
+                    )
+                )
+                ->execute()
+                ->fetchColumn(0);
+
+            $pass = !$recordCount;
             $Ttable = 'pages_language_overlay';
         } else {
-            $pass = !BackendUtility::getRecordLocalization($table, $uid, $langRec['uid'], ('AND pid=' . (int)$row['pid']));
+            $pass = !BackendUtility::getRecordLocalization($table, $uid, $langRec['uid'], 'AND pid=' . (int)$row['pid']);
             $Ttable = $table;
         }
 
@@ -5472,23 +5564,39 @@ class DataHandler
         if (!BackendUtility::isTableLocalizable($table) || $table === 'pages' || $table === 'pages_language_overlay') {
             return;
         }
-        $where = '';
+
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
+        $queryBuilder->getRestrictions()
+            ->removeAll()
+            ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+            ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+        $queryBuilder->select('*')
+            ->from($table)
+            ->where(
+                $queryBuilder->expr()->eq(
+                    $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'],
+                    $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
+                )
+            );
+
         if (isset($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) && $GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
-            $where = ' AND t3ver_oid=0';
+            $queryBuilder->andWhere(
+                $queryBuilder->expr()->eq('t3ver_oid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
+            );
         }
-        $l10nRecords = BackendUtility::getRecordsByField($table, $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'], $uid, $where);
-        if (is_array($l10nRecords)) {
-            foreach ($l10nRecords as $record) {
-                // Ignore workspace delete placeholders. Those records have been marked for
-                // deletion before - deleting them again in a workspace would revert that state.
-                if ($this->BE_USER->workspace > 0 && BackendUtility::isTableWorkspaceEnabled($table)) {
-                    BackendUtility::workspaceOL($table, $record);
-                    if (VersionState::cast($record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) {
-                        continue;
-                    }
+
+        $result = $queryBuilder->execute();
+        while ($record = $result->fetch()) {
+            // Ignore workspace delete placeholders. Those records have been marked for
+            // deletion before - deleting them again in a workspace would revert that state.
+            if ($this->BE_USER->workspace > 0 && BackendUtility::isTableWorkspaceEnabled($table)) {
+                BackendUtility::workspaceOL($table, $record);
+                if (VersionState::cast($record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) {
+                    continue;
                 }
-                $this->deleteAction($table, (int)$record['t3ver_oid'] > 0 ? (int)$record['t3ver_oid'] : (int)$record['uid']);
             }
+            $this->deleteAction($table, (int)$record['t3ver_oid'] > 0 ? (int)$record['t3ver_oid'] : (int)$record['uid']);
         }
     }
 
diff --git a/typo3/sysext/core/Classes/Database/Query/QueryBuilder.php b/typo3/sysext/core/Classes/Database/Query/QueryBuilder.php
index 5720b42a2ee1df8e70a5dbaafb8cab8251358762..4b2ab3571da0d4b05b80c54c73a35d4a18d362e6 100644
--- a/typo3/sysext/core/Classes/Database/Query/QueryBuilder.php
+++ b/typo3/sysext/core/Classes/Database/Query/QueryBuilder.php
@@ -209,11 +209,11 @@ class QueryBuilder
      *
      * @param string|int $key The parameter position or name.
      * @param mixed $value The parameter value.
-     * @param string|null $type One of the Connection::PARAM_* constants.
+     * @param int|null $type One of the Connection::PARAM_* constants.
      *
      * @return QueryBuilder This QueryBuilder instance.
      */
-    public function setParameter($key, $value, string $type = null): QueryBuilder
+    public function setParameter($key, $value, int $type = null): QueryBuilder
     {
         $this->concreteQueryBuilder->setParameter($key, $value, $type);
 
diff --git a/typo3/sysext/core/Classes/Database/SoftReferenceIndex.php b/typo3/sysext/core/Classes/Database/SoftReferenceIndex.php
index b2891282e0c417ad4e6a54971601ab3db75d6d89..98beccd4a498da686e4beaaf49dabae6bbb050c5 100644
--- a/typo3/sysext/core/Classes/Database/SoftReferenceIndex.php
+++ b/typo3/sysext/core/Classes/Database/SoftReferenceIndex.php
@@ -14,6 +14,8 @@ namespace TYPO3\CMS\Core\Database;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
+use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
 use TYPO3\CMS\Core\LinkHandling\LinkService;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\Service\TypoLinkCodecService;
@@ -616,13 +618,27 @@ class SoftReferenceIndex
     /**
      * Look up and return page uid for alias
      *
-     * @param int $link_param Page alias string value
+     * @param string $link_param Page alias string value
      * @return int Page uid corresponding to alias value.
      */
     public function getPageIdFromAlias($link_param)
     {
-        $pRec = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordsByField('pages', 'alias', $link_param);
-        return $pRec[0]['uid'];
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
+        $queryBuilder->getRestrictions()
+            ->removeAll()
+            ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+            ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+        $pageUid = $queryBuilder->select('uid')
+            ->from('pages')
+            ->where(
+                $queryBuilder->expr()->eq('alias', $queryBuilder->createNamedParameter($link_param, \PDO::PARAM_STR))
+            )
+            ->setMaxResults(1)
+            ->execute()
+            ->fetchColumn(0);
+
+        return (int)$pageUid;
     }
 
     /**
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-79122-DeprecateBackendUtilitygetRecordsByField.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-79122-DeprecateBackendUtilitygetRecordsByField.rst
new file mode 100644
index 0000000000000000000000000000000000000000..07098d0392c95ae178d70464b583a4010242bac6
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-79122-DeprecateBackendUtilitygetRecordsByField.rst
@@ -0,0 +1,32 @@
+.. include:: ../../Includes.txt
+
+========================================================
+Deprecation: #79122 - Deprecate method getRecordsByField
+========================================================
+
+See :issue:`79122`
+
+Description
+===========
+
+The method :php:`TYPO3\CMS\Backend\Utility\BackendUtility::getRecordsByField()` has been deprecated and should not be used any longer.
+
+
+Impact
+======
+
+Calling the deprecated :php:`getRecordsByField()` method will trigger a deprecation log entry.
+
+
+Affected Installations
+======================
+
+Any installation using the mentioned method :php:`getRecordsByField()`.
+
+
+Migration
+=========
+
+Use the `ConnectionPool` and the `QueryBuilder` classes directly to query the database from your code.
+
+.. index:: Backend
diff --git a/typo3/sysext/recordlist/Classes/LinkHandler/PageLinkHandler.php b/typo3/sysext/recordlist/Classes/LinkHandler/PageLinkHandler.php
index 48f2179ae7f38c6a213600c5f5e5d299c5196c0f..7f9231cdad0a5d2fad4b6dfa75d30a220c463b48 100644
--- a/typo3/sysext/recordlist/Classes/LinkHandler/PageLinkHandler.php
+++ b/typo3/sysext/recordlist/Classes/LinkHandler/PageLinkHandler.php
@@ -62,11 +62,29 @@ class PageLinkHandler extends AbstractLinkHandler implements LinkHandlerInterfac
         $data = $linkParts['url'];
         // Checking if the id-parameter is an alias.
         if (isset($data['pagealias'])) {
-            $records = BackendUtility::getRecordsByField('pages', 'alias', $data['pagealias']);
-            if (empty($records)) {
+            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+                ->getQueryBuilderForTable('pages');
+            $queryBuilder->getRestrictions()
+                ->removeAll()
+                ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+                ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+            $pageUid = $queryBuilder->select('uid')
+                ->from('pages')
+                ->where(
+                    $queryBuilder->expr()->eq(
+                        'alias',
+                        $queryBuilder->createNamedParameter($data['pagealias'], \PDO::PARAM_STR)
+                    )
+                )
+                ->setMaxResults(1)
+                ->execute()
+                ->fetchColumn(0);
+
+            if ($pageUid === false) {
                 return false;
             }
-            $data['pageuid'] = (int)$records[0]['uid'];
+            $data['pageuid'] = (int)$pageUid;
         }
         // Check if the page still exists
         if ((int)$data['pageuid'] > 0) {
diff --git a/typo3/sysext/recycler/Classes/Domain/Model/DeletedRecords.php b/typo3/sysext/recycler/Classes/Domain/Model/DeletedRecords.php
index 7ad57088a5addf4457cb6a461551dba0bb683d78..ed1c04795b27fb1a8f3e4a8e0543a9379c4741a1 100644
--- a/typo3/sysext/recycler/Classes/Domain/Model/DeletedRecords.php
+++ b/typo3/sysext/recycler/Classes/Domain/Model/DeletedRecords.php
@@ -16,6 +16,8 @@ namespace TYPO3\CMS\Recycler\Domain\Model;
 
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Database\Query\QueryBuilder;
+use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
@@ -89,22 +91,22 @@ class DeletedRecords
         // set the limit
         $this->limit = trim($limit);
         if ($table) {
-            if (in_array($table, RecyclerUtility::getModifyableTables())) {
+            if (in_array($table, RecyclerUtility::getModifyableTables(), true)) {
                 $this->table[] = $table;
-                $this->setData($id, $table, $depth, $GLOBALS['TCA'][$table]['ctrl'], $filter);
+                $this->setData($id, $table, $depth, $filter);
             }
         } else {
-            foreach ($GLOBALS['TCA'] as $tableKey => $tableValue) {
+            foreach (array_keys($GLOBALS['TCA']) as $tableKey) {
                 // only go into this table if the limit allows it
                 if ($this->limit !== '') {
-                    $parts = GeneralUtility::trimExplode(',', $this->limit);
+                    $parts = GeneralUtility::intExplode(',', $this->limit, true);
                     // abort loop if LIMIT 0,0
-                    if ((int)$parts[0] === 0 && (int)$parts[1] === 0) {
+                    if ($parts[0] === 0 && $parts[1] === 0) {
                         break;
                     }
                 }
                 $this->table[] = $tableKey;
-                $this->setData($id, $tableKey, $depth, $tableValue['ctrl'], $filter);
+                $this->setData($id, $tableKey, $depth, $filter);
             }
         }
         return $this;
@@ -135,67 +137,41 @@ class DeletedRecords
      * @param int $id UID from record
      * @param string $table Tablename from record
      * @param int $depth How many levels recursive
-     * @param array $tcaCtrl TCA CTRL array
      * @param string $filter Filter text
      * @return void
      */
-    protected function setData($id, $table, $depth, $tcaCtrl, $filter)
+    protected function setData($id, $table, $depth, $filter)
     {
-        $id = (int)$id;
-        if (!array_key_exists('delete', $tcaCtrl)) {
+        if (!array_key_exists('delete', $GLOBALS['TCA'][$table]['ctrl'])) {
             return;
         }
-        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
-        $queryBuilder->getRestrictions()->removeAll();
 
-        // find the 'deleted' field for this table
+        $id = (int)$id;
+        $tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
         $deletedField = RecyclerUtility::getDeletedField($table);
-
-        // create the filter WHERE-clause
-        $filterConstraint = null;
-        if (trim($filter) !== '') {
-            $labelConstraint = $queryBuilder->expr()->like(
-                $tcaCtrl['label'],
-                $queryBuilder->createNamedParameter(
-                    $queryBuilder->quote('%' . $queryBuilder->escapeLikeWildcards($filter) . '%'),
-                    \PDO::PARAM_STR
-                )
-            );
-            if (MathUtility::canBeInterpretedAsInteger($filter)) {
-                $filterConstraint = $queryBuilder->expr()->orX(
-                    $queryBuilder->expr()->eq(
-                        'uid',
-                        $queryBuilder->createNamedParameter($filter, \PDO::PARAM_INT)
-                    ),
-                    $queryBuilder->expr()->eq(
-                        'pid',
-                        $queryBuilder->createNamedParameter($filter, \PDO::PARAM_INT)
-                    ),
-                    $labelConstraint
-                );
-            } else {
-                $filterConstraint = $labelConstraint;
-            }
-        }
+        $firstResult = 0;
+        $maxResults = 0;
 
         // get the limit
         if (!empty($this->limit)) {
             // count the number of deleted records for this pid
-            $deletedCount = $queryBuilder
+            $queryBuilder = $this->getFilteredQueryBuilder($table, $id, $filter);
+            $queryBuilder->getRestrictions()->removeAll();
+
+            $deletedCount = (int)$queryBuilder
                 ->count('*')
                 ->from($table)
-                ->where(
-                    $queryBuilder->expr()->neq($deletedField, $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)),
-                    $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)),
-                    $filterConstraint
+                ->andWhere(
+                    $queryBuilder->expr()->neq(
+                        $deletedField,
+                        $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
+                    )
                 )
                 ->execute()
-                ->fetchColumn();
+                ->fetchColumn(0);
 
             // split the limit
-            $parts = GeneralUtility::trimExplode(',', $this->limit);
-            $offset = $parts[0];
-            $rowCount = $parts[1];
+            list($offset, $rowCount) = GeneralUtility::intExplode(',', $this->limit, true);
             // subtract the number of deleted records from the limit's offset
             $result = $offset - $deletedCount;
             // if the result is >= 0
@@ -206,14 +182,12 @@ class DeletedRecords
                 // do NOT query this depth; limit also does not need to be set, we set it anyways
                 $allowQuery = false;
                 $allowDepth = true;
-                $limit = '';
             } else {
                 // the offset for the temporary limit has to remain like the original offset
                 // in case the original offset was just crossed by the amount of deleted records
+                $tempOffset = 0;
                 if ($offset !== 0) {
                     $tempOffset = $offset;
-                } else {
-                    $tempOffset = 0;
                 }
                 // set the offset in the limit to 0
                 $newOffset = 0;
@@ -222,7 +196,8 @@ class DeletedRecords
                 // if the result now is > limit's row count
                 if ($absResult > $rowCount) {
                     // use the limit's row count as the temporary limit
-                    $limit = implode(',', [$tempOffset, $rowCount]);
+                    $firstResult = $tempOffset;
+                    $maxResults = $rowCount;
                     // set the limit's row count to 0
                     $this->limit = implode(',', [$newOffset, 0]);
                     // do not go into new depth
@@ -230,7 +205,8 @@ class DeletedRecords
                 } else {
                     // if the result now is <= limit's row count
                     // use the result as the temporary limit
-                    $limit = implode(',', [$tempOffset, $absResult]);
+                    $firstResult = $tempOffset;
+                    $maxResults = $absResult;
                     // subtract the result from the row count
                     $newCount = $rowCount - $absResult;
                     // store the new result in the limit's row count
@@ -249,31 +225,35 @@ class DeletedRecords
                 $allowQuery = true;
             }
         } else {
-            $limit = '';
             $allowDepth = true;
             $allowQuery = true;
         }
         // query for actual deleted records
         if ($allowQuery) {
-            $where = $queryBuilder->expr()->andX(
-                $queryBuilder->expr()->eq(
-                    'pid',
-                    $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)
-                ),
-                $filterConstraint
-            );
-            $recordsToCheck = BackendUtility::getRecordsByField(
-                $table,
-                $deletedField,
-                '1',
-                ' AND ' . $where,
-                '',
-                'uid',
-                $limit,
-                false,
-                $queryBuilder
-            );
-            if ($recordsToCheck) {
+            $queryBuilder = $this->getFilteredQueryBuilder($table, $id, $filter);
+            if ($firstResult) {
+                $queryBuilder->setFirstResult($firstResult);
+            }
+            if ($maxResults) {
+                $queryBuilder->setMaxResults($maxResults);
+            }
+            $recordsToCheck = $queryBuilder->select('*')
+                ->from($table)
+                ->andWhere(
+                    $queryBuilder->expr()->eq(
+                        'pid',
+                        $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)
+                    ),
+                    $queryBuilder->expr()->eq(
+                        $deletedField,
+                        $queryBuilder->createNamedParameter(1, \PDO::PARAM_INT)
+                    )
+                )
+                ->orderBy('uid')
+                ->execute()
+                ->fetchAll();
+
+            if ($recordsToCheck !== false) {
                 $this->checkRecordAccess($table, $recordsToCheck);
             }
         }
@@ -290,12 +270,12 @@ class DeletedRecords
                 ->execute();
 
             while ($row = $resPages->fetch()) {
-                $this->setData($row['uid'], $table, $depth - 1, $tcaCtrl, $filter);
+                $this->setData($row['uid'], $table, $depth - 1, $filter);
                 // some records might have been added, check if we still have the limit for further queries
                 if (!empty($this->limit)) {
-                    $parts = GeneralUtility::trimExplode(',', $this->limit);
+                    $parts = GeneralUtility::intExplode(',', $this->limit, true);
                     // abort loop if LIMIT 0,0
-                    if ((int)$parts[0] === 0 && (int)$parts[1] === 0) {
+                    if ($parts[0] === 0 && $parts[1] === 0) {
                         $resPages->closeCursor();
                         break;
                     }
@@ -306,6 +286,55 @@ class DeletedRecords
         $this->title[$table] = $tcaCtrl['title'];
     }
 
+    /**
+     * Helper method for setData() to create a QueryBuilder that filters the records by default.
+     *
+     * @param string $table
+     * @param int $pid
+     * @param string $filter
+     * @return \TYPO3\CMS\Core\Database\Query\QueryBuilder
+     * @throws \InvalidArgumentException
+     */
+    protected function getFilteredQueryBuilder(string $table, int $pid, string $filter): QueryBuilder
+    {
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
+        $queryBuilder->getRestrictions()
+            ->removeAll()
+            ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+        // create the filter WHERE-clause
+        $filterConstraint = null;
+        if (trim($filter) !== '') {
+            $filterConstraint = $queryBuilder->expr()->like(
+                $GLOBALS['TCA'][$table]['ctrl']['label'],
+                $queryBuilder->createNamedParameter(
+                    $queryBuilder->quote('%' . $queryBuilder->escapeLikeWildcards($filter) . '%'),
+                    \PDO::PARAM_STR
+                )
+            );
+            if (MathUtility::canBeInterpretedAsInteger($filter)) {
+                $filterConstraint = $queryBuilder->expr()->orX(
+                    $queryBuilder->expr()->eq(
+                        'uid',
+                        $queryBuilder->createNamedParameter($filter, \PDO::PARAM_INT)
+                    ),
+                    $queryBuilder->expr()->eq(
+                        'pid',
+                        $queryBuilder->createNamedParameter($filter, \PDO::PARAM_INT)
+                    ),
+                    $filterConstraint
+                );
+            }
+        }
+
+        $queryBuilder->where(
+            $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pid, \PDO::PARAM_INT)),
+            $filterConstraint
+        );
+
+        return $queryBuilder;
+    }
+
     /**
      * Checks whether the current backend user has access to the given records.
      *
diff --git a/typo3/sysext/workspaces/Classes/Service/WorkspaceService.php b/typo3/sysext/workspaces/Classes/Service/WorkspaceService.php
index b1b7fe03bab4b232c5bb4128a57fc32247c79be2..4f8cbf6eccc209f8fae1d16e05072f5aa33e5d0f 100644
--- a/typo3/sysext/workspaces/Classes/Service/WorkspaceService.php
+++ b/typo3/sysext/workspaces/Classes/Service/WorkspaceService.php
@@ -14,11 +14,13 @@ namespace TYPO3\CMS\Workspaces\Service;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Database\ConnectionPool;
-use TYPO3\CMS\Core\Database\Query\Restriction;
+use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
+use TYPO3\CMS\Core\Database\Query\Restriction\RootLevelRestriction;
 use TYPO3\CMS\Core\SingletonInterface;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
@@ -64,7 +66,7 @@ class WorkspaceService implements SingletonInterface
 
         $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_workspace');
         $queryBuilder->getRestrictions()
-            ->add(GeneralUtility::makeInstance(Restriction\RootLevelRestriction::class));
+            ->add(GeneralUtility::makeInstance(RootLevelRestriction::class));
 
         $result = $queryBuilder
             ->select('uid', 'title', 'adminusers', 'members')
@@ -1102,24 +1104,36 @@ class WorkspaceService implements SingletonInterface
     {
         $languageOptions = [];
         /** @var \TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider $translationConfigurationProvider */
-        $translationConfigurationProvider = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider::class);
+        $translationConfigurationProvider = GeneralUtility::makeInstance(TranslationConfigurationProvider::class);
         $systemLanguages = $translationConfigurationProvider->getSystemLanguages($pageId);
 
         if ($GLOBALS['BE_USER']->checkLanguageAccess(0)) {
             // Use configured label for default language
             $languageOptions[0] = $systemLanguages[0]['title'];
         }
-        $pages = BackendUtility::getRecordsByField('pages_language_overlay', 'pid', $pageId);
 
-        if (!is_array($pages)) {
-            return $languageOptions;
-        }
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+            ->getQueryBuilderForTable('pages_language_overlay');
+        $queryBuilder->getRestrictions()
+            ->removeAll()
+            ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+            ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
+
+        $result = $queryBuilder->select('sys_language_uid')
+            ->from('pages_language_overlay')
+            ->where(
+                $queryBuilder->expr()->eq(
+                    'pid',
+                    $queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
+                )
+            )
+            ->execute();
 
-        foreach ($pages as $page) {
-            $languageId = (int)$page['sys_language_uid'];
+        while ($row = $result->fetch()) {
+            $languageId = (int)$row['sys_language_uid'];
             // Only add links to active languages the user has access to
             if (isset($systemLanguages[$languageId]) && $GLOBALS['BE_USER']->checkLanguageAccess($languageId)) {
-                $languageOptions[$page['sys_language_uid']] = $systemLanguages[$languageId]['title'];
+                $languageOptions[$languageId] = $systemLanguages[$languageId]['title'];
             }
         }