diff --git a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
index 9ec9758185..bed13f225d 100644
--- a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
+++ b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
@@ -18,6 +18,10 @@ views.argument.taxonomy_index_tid_depth:
       type: boolean
       label: 'Use taxonomy term path'
 
+views.argument.taxonomy_index_tid_depth_join:
+  type: views.argument.taxonomy_index_tid_depth
+  label: 'Taxonomy term ID with depth (using joins)'
+
 views.argument.taxonomy_index_tid_depth_modifier:
   type: views_argument
   label: 'Taxonomy depth modifier'
@@ -150,6 +154,10 @@ views.filter.taxonomy_index_tid_depth:
       type: integer
       label: 'Depth'
 
+views.filter.taxonomy_index_tid_depth_join:
+  type: views.filter.taxonomy_index_tid_depth
+  label: 'Taxonomy term ID with depth (using joins)'
+
 views.relationship.node_term_data:
   type: views_relationship
   label: 'Taxonomy term'
diff --git a/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepthJoin.php b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepthJoin.php
new file mode 100644
index 0000000000..44b50797fb
--- /dev/null
+++ b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepthJoin.php
@@ -0,0 +1,120 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Plugin\views\argument\IndexTidDepthJoin.
+ */
+
+namespace Drupal\taxonomy\Plugin\views\argument;
+
+use Drupal\views\Views;
+
+/**
+ * Argument handler for taxonomy terms with depth using joins.
+ *
+ * This handler can be more performant than the normal one due to the fact that
+ * it uses joins instead of subqueries.
+ *
+ * @ingroup views_argument_handlers
+ *
+ * @ViewsArgument("taxonomy_index_tid_depth_join")
+ */
+class IndexTidDepthJoin extends IndexTidDepth {
+
+  public function query($group_by = FALSE) {
+    $this->ensureMyTable();
+
+    if (!empty($this->options['break_phrase'])) {
+      $break = static::breakString($this->argument);
+      if ($break->value === array(-1)) {
+        return FALSE;
+      }
+
+      $operator = (count($break->value) > 1) ? 'IN' : '=';
+      $tids = $break->value;
+    }
+    else {
+      $operator = "=";
+      $tids = $this->argument;
+    }
+
+    // The tids variable can be an integer or an array of integers.
+    $tids = is_array($tids) ? $tids : array($tids);
+
+    if ($this->options['depth'] > 0) {
+      // When the depth is positive search the children.
+      foreach ($tids as $tid) {
+        // The term must be loaded to get vid for use in taxonomy_get_tree().
+        if ($term = $this->termStorage->load($tid)) {
+          // For every tid argument find all the children down to the depth set
+          // in the options and save the tids for the condition.
+          $tree = $this->termStorage->loadTree($term->getVocabularyId(), $term->id(), (int) $this->options['depth']);
+          $tids_from_tree = [];
+          foreach ($tree as $item) {
+            $tids_from_tree[] = $item->tid;
+          }
+          $tids = array_merge($tids, $tids_from_tree);
+        }
+      }
+    }
+    elseif ($this->options['depth'] < 0) {
+      // When the depth is negative search the parents.
+      foreach ($tids as $tid) {
+        // For every tid argument find all the parents up to the depth set
+        // in the options and add the tids into the array. Since there is
+        // no taxonomy function to get all parents with a depth limit it
+        // is done here building a multidimensional array.
+        if ($term = $this->termStorage->load($tid)) {
+          // A variable is needed to track the current depth level.
+          $n = 0;
+          // Initialise our depth based parents array with the leaf term.
+          $parents[$n--][] = $term;
+          while ($n >= $this->options['depth']) {
+            // At each depth find the parents of the current terms.
+            // It is important to note that it is possible for a term to have
+            // multiple parents so get the parents of every parent and so on.
+            $parents[$n] = array();
+            foreach ($parents[$n + 1] as $term) {
+              $parents[$n] += $this->termStorage->loadParents($term->id());
+            }
+            // Save all the tids for the condition.
+            $tids = array_merge($tids, array_map(function ($term) {
+              return $term->id();
+            }, $parents[$n]));
+            $n--;
+          }
+        }
+      }
+    }
+
+    // Check the size of the array and set the operator accordingly.
+    if (count($tids) > 1) {
+      $operator = 'IN';
+    }
+    else {
+      $tids = current($tids);
+      $operator = '=';
+    }
+
+    // Join on taxonomy index table.
+    $configuration = array(
+      'table' => 'taxonomy_index',
+      'field' => 'nid',
+      'left_table' => $this->tableAlias,
+      'left_field' => $this->realField,
+      'operator' => $operator,
+      'extra' => array(
+        0 => array(
+          'field' => 'tid',
+          'value' => $tids,
+        ),
+      ),
+    );
+    $join = Views::pluginManager('join')->createInstance('standard', $configuration);
+    $this->query->addRelationship('taxonomy_index', $join, 'node');
+
+    // Distinct is required to prevent duplicate rows.
+    $this->query->distinct = TRUE;
+  }
+
+}
diff --git a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepthJoin.php b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepthJoin.php
new file mode 100644
index 0000000000..42798e9eda
--- /dev/null
+++ b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepthJoin.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace Drupal\taxonomy\Plugin\views\filter;
+
+use Drupal\views\Views;
+
+/**
+ * Filter handler for taxonomy terms with depth using joins.
+ *
+ * This handler can be more performant than the normal one due to the fact that
+ * it uses joins instead of subqueries.
+ *
+ * @ingroup views_filter_handlers
+ *
+ * @ViewsFilter("taxonomy_index_tid_depth_join")
+ */
+class TaxonomyIndexTidDepthJoin extends TaxonomyIndexTidDepth {
+
+  public function query() {
+    // If no filter values are present, then do nothing.
+    if (count($this->value) == 0) {
+      return;
+    }
+    elseif (count($this->value) == 1) {
+      // Sometimes $this->value is an array with a single element so convert it.
+      if (is_array($this->value)) {
+        $this->value = current($this->value);
+      }
+      $operator = '=';
+    }
+    else {
+      $operator = 'IN';# " IN (" . implode(', ', array_fill(0, sizeof($this->value), '%d')) . ")";
+    }
+
+    // The normal use of ensureMyTable() here breaks Views.
+    // So instead we trick the filter into using the alias of the base table.
+    //   See https://www.drupal.org/node/271833.
+    // If a relationship is set, we must use the alias it provides.
+    if (!empty($this->relationship)) {
+      $this->tableAlias = $this->relationship;
+    }
+    // If no relationship, then use the alias of the base table.
+    else {
+      $this->tableAlias = $this->query->ensureTable($this->view->storage->get('base_table'));
+    }
+
+    // The tids variable can be an integer or an array of integers.
+    $tids = is_array($this->value) ? $this->value : array($this->value);
+
+    if ($this->options['depth'] > 0) {
+      // When the depth is positive search the children.
+      foreach ($tids as $tid) {
+        // The term must be loaded to get vid for use in taxonomy_get_tree().
+        if ($term = $this->termStorage->load($tid)) {
+          // For every tid argument find all the children down to the depth set
+          // in the options and save the tids for the condition.
+          $tree = $this->termStorage->loadTree($term->getVocabularyId(), $term->id(), (int) $this->options['depth']);
+          $tids = array_merge($tids, array_map(function ($term) {
+            return $term->id();
+          }, $tree));
+        }
+      }
+    }
+    elseif ($this->options['depth'] < 0) {
+      // When the depth is negative search the parents.
+      foreach ($tids as $tid) {
+        // For every tid argument find all the parents up to the depth set
+        // in the options and add the tids into the array. Since there is
+        // no taxonomy function to get all parents with a depth limit it
+        // is done here building a multidimensional array.
+        if ($term = $this->termStorage->load($tid)) {
+          // A variable is needed to track the current depth level.
+          $n = 0;
+          // Initialise our depth based parents array with the leaf term.
+          $parents[$n--][] = $term;
+          while ($n >= $this->options['depth']) {
+            // At each depth find the parents of the current terms.
+            // It is important to note that it is possible for a term to have
+            // multiple parents so get the parents of every parent and so on.
+            $parents[$n] = array();
+            foreach ($parents[$n + 1] as $term) {
+              $parents[$n] += $this->termStorage->loadParents($term->id());
+            }
+            // Save all the tids for the condition.
+            $tids = array_merge($tids, array_map(function ($term) {
+              return $term->id();
+            }, $parents[$n]));
+            $n--;
+          }
+        }
+      }
+    }
+
+    // Check the size of the array and set the operator accordingly.
+    if (count($tids) > 1) {
+      $operator = 'IN';
+    }
+    else {
+      $tids = current($tids);
+      $operator = '=';
+    }
+
+    // Join on taxonomy index table.
+    $configuration = array(
+      'table' => 'taxonomy_index',
+      'field' => 'nid',
+      'left_table' => $this->tableAlias,
+      'left_field' => $this->realField,
+      'operator' => $operator,
+      'extra' => array(
+        0 => array(
+          'field' => 'tid',
+          'value' => $tids,
+        ),
+      ),
+    );
+    $join = Views::pluginManager('join')->createInstance('standard', $configuration);
+
+    $this->query->addRelationship('taxonomy_index', $join, 'node');
+  }
+
+}
diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermArgumentDepthJoinTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermArgumentDepthJoinTest.php
new file mode 100644
index 0000000000..89ce5253f7
--- /dev/null
+++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermArgumentDepthJoinTest.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Drupal\taxonomy\Tests\Views;
+
+/**
+ * Tests the taxonomy term with depth argument.
+ *
+ * @group taxonomy
+ */
+class TaxonomyTermArgumentDepthJoinTest extends TaxonomyTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['taxonomy', 'taxonomy_test_views', 'views', 'node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $testViews = ['test_argument_taxonomy_index_tid_depth_join'];
+
+  /**
+   * @var \Drupal\taxonomy\TermInterface[]
+   */
+  protected $terms = [];
+
+  /**
+   * @var \Drupal\views\ViewExecutable
+   */
+  protected $view;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Create a term with markup in the label.
+    $first = $this->createTerm(['name' => '<em>First</em>']);
+
+    // Create a node w/o any terms.
+    $settings = ['type' => 'article'];
+
+    // Create a node with linked to the term.
+    $settings['field_views_testing_tags'][0]['target_id'] = $first->id();
+    $this->nodes[] = $this->drupalCreateNode($settings);
+
+    $this->terms[0] = $first;
+  }
+
+  /**
+   * Tests title escaping.
+   */
+  public function testTermWithDepthArgumentTitleEscaping() {
+    $this->drupalGet('test_argument_taxonomy_index_tid_depth_join/' . $this->terms[0]->id());
+    $this->assertEscaped($this->terms[0]->label());
+  }
+
+}
diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermFilterDepthJoinTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermFilterDepthJoinTest.php
new file mode 100644
index 0000000000..9b268af0e8
--- /dev/null
+++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermFilterDepthJoinTest.php
@@ -0,0 +1,136 @@
+<?php
+
+namespace Drupal\taxonomy\Tests\Views;
+
+use Drupal\views\Views;
+
+/**
+ * Test the taxonomy term with depth filter.
+ *
+ * @group taxonomy
+ */
+class TaxonomyTermFilterDepthJoinTest extends TaxonomyTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['taxonomy', 'taxonomy_test_views', 'views', 'node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $testViews = ['test_filter_taxonomy_index_tid_depth_join'];
+
+  /**
+   * @var \Drupal\taxonomy\TermInterface[]
+   */
+  protected $terms = [];
+
+  /**
+   * @var \Drupal\views\ViewExecutable
+   */
+  protected $view;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Create a hierarchy 3 deep. Note the parent setup function creates two
+    // top-level terms w/o children.
+    $first = $this->createTerm(['name' => 'First']);
+    $second = $this->createTerm(['name' => 'Second', 'parent' => $first->id()]);
+    $third = $this->createTerm(['name' => 'Third', 'parent' => $second->id()]);
+
+    // Create a node w/o any terms.
+    $settings = ['type' => 'article'];
+    $this->nodes[] = $this->drupalCreateNode($settings);
+
+    // Create a node with only the top level term.
+    $settings['field_views_testing_tags'][0]['target_id'] = $first->id();
+    $this->nodes[] = $this->drupalCreateNode($settings);
+
+    // Create a node with only the third level term.
+    $settings['field_views_testing_tags'][0]['target_id'] = $third->id();
+    $this->nodes[] = $this->drupalCreateNode($settings);
+
+    $this->terms[0] = $first;
+    $this->terms[1] = $second;
+    $this->terms[2] = $third;
+
+    $this->view = Views::getView('test_filter_taxonomy_index_tid_depth_join');
+  }
+
+  /**
+   * Tests the terms with depth filter.
+   */
+  public function testTermWithDepthFilter() {
+    $column_map = ['nid' => 'nid'];
+    $assert_method = 'assertIdentical';
+
+    // Default view has an empty value for this filter, so all nodes should be
+    // returned.
+    $expected = [
+      ['nid' => 1],
+      ['nid' => 2],
+      ['nid' => 3],
+      ['nid' => 4],
+      ['nid' => 5],
+    ];
+    $this->executeView($this->view);
+    $this->assertIdenticalResultsetHelper($this->view, $expected, $column_map, $assert_method);
+
+    // Set filter to search on top-level term, with depth 0.
+    $expected = [['nid' => 4]];
+    $this->assertTermWithDepthResult($this->terms[0]->id(), 0, $expected);
+
+    // Top-level term, depth 1.
+    $expected = [['nid' => 4]];
+    $this->assertTermWithDepthResult($this->terms[0]->id(), 0, $expected);
+
+    // Top-level term, depth 2.
+    $expected = [['nid' => 4], ['nid' => 5]];
+    $this->assertTermWithDepthResult($this->terms[0]->id(), 2, $expected);
+
+    // Second-level term, depth 1.
+    $expected = [['nid' => 5]];
+    $this->assertTermWithDepthResult($this->terms[1]->id(), 1, $expected);
+
+    // Third-level term, depth 0.
+    $expected = [['nid' => 5]];
+    $this->assertTermWithDepthResult($this->terms[2]->id(), 0, $expected);
+
+    // Third-level term, depth 1.
+    $expected = [['nid' => 5]];
+    $this->assertTermWithDepthResult($this->terms[2]->id(), 1, $expected);
+
+    // Third-level term, depth -2.
+    $expected = [['nid' => 4], ['nid' => 5]];
+    $this->assertTermWithDepthResult($this->terms[2]->id(), -2, $expected);
+  }
+
+  /**
+   * Changes the tid filter to given term and depth.
+   *
+   * @param int $tid
+   *   The term ID to filter on.
+   * @param int $depth
+   *   The depth to search.
+   * @param array $expected
+   *   The expected views result.
+   */
+  protected function assertTermWithDepthResult($tid, $depth, array $expected) {
+    $this->view->destroy();
+    $this->view->initDisplay();
+    $filters = $this->view->displayHandlers->get('default')
+      ->getOption('filters');
+    $filters['tid_depth']['depth'] = $depth;
+    $filters['tid_depth']['value'] = [$tid];
+    $this->view->displayHandlers->get('default')
+      ->setOption('filters', $filters);
+    $this->executeView($this->view);
+    $this->assertIdenticalResultsetHelper($this->view, $expected, ['nid' => 'nid'], 'assertIdentical');
+  }
+
+}
diff --git a/core/modules/taxonomy/taxonomy.views.inc b/core/modules/taxonomy/taxonomy.views.inc
index 5360d50814..789526ee80 100644
--- a/core/modules/taxonomy/taxonomy.views.inc
+++ b/core/modules/taxonomy/taxonomy.views.inc
@@ -42,6 +42,20 @@ function taxonomy_views_data_alter(&$data) {
     ),
   );
 
+  $data['node_field_data']['term_node_tid_depth_join'] = array(
+    'help' => t('Display content if it has the selected taxonomy terms, or children of the selected terms. Due to additional complexity, this has fewer options than the versions without depth.'),
+    'real field' => 'nid',
+    'argument' => array(
+      'title' => t('Has taxonomy term ID with depth (using joins)'),
+      'id' => 'taxonomy_index_tid_depth_join',
+      'accept depth modifier' => TRUE,
+    ),
+    'filter' => array(
+      'title' => t('Has taxonomy terms with depth (using joins)'),
+      'id' => 'taxonomy_index_tid_depth_join',
+    ),
+  );
+
   $data['node_field_data']['term_node_tid_depth_modifier'] = array(
     'title' => t('Has taxonomy term ID depth modifier'),
     'help' => t('Allows the "depth" for Taxonomy: Term ID (with depth) to be modified via an additional contextual filter value.'),
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_argument_taxonomy_index_tid_depth_join.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_argument_taxonomy_index_tid_depth_join.yml
new file mode 100644
index 0000000000..64fa12b5c4
--- /dev/null
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_argument_taxonomy_index_tid_depth_join.yml
@@ -0,0 +1,227 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
+    - taxonomy
+    - user
+id: test_argument_taxonomy_index_tid_depth_join
+label: test_argument_taxonomy_index_tid_depth_join
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Filter
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: full
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: '‹ Previous'
+            next: 'Next ›'
+            first: '« First'
+            last: 'Last »'
+          quantity: 9
+      style:
+        type: default
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          uses_fields: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          entity_type: node
+          entity_field: title
+          label: ''
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            trim: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            html: false
+          hide_empty: false
+          empty_zero: false
+          settings:
+            link_to_entity: true
+          plugin_id: field
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exclude: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+      filters:
+        status:
+          value: '1'
+          table: node_field_data
+          field: status
+          plugin_id: boolean
+          entity_type: node
+          entity_field: status
+          id: status
+          expose:
+            operator: ''
+          group: 1
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          order: DESC
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exposed: false
+          expose:
+            label: ''
+          granularity: second
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments:
+        term_node_tid_depth:
+          id: term_node_tid_depth
+          table: node_field_data
+          field: term_node_tid_depth
+          relationship: none
+          group_type: group
+          admin_label: ''
+          default_action: ignore
+          exception:
+            value: all
+            title_enable: false
+            title: All
+          title_enable: true
+          title: '{{ arguments.term_node_tid_depth }}'
+          default_argument_type: fixed
+          default_argument_options:
+            argument: ''
+          default_argument_skip_url: false
+          summary_options:
+            base_path: ''
+            count: true
+            items_per_page: 25
+            override: false
+          summary:
+            sort_order: asc
+            number_of_records: 0
+            format: default_summary
+          specify_validation: false
+          validate:
+            type: none
+            fail: 'not found'
+          validate_options: {  }
+          depth: 0
+          break_phrase: false
+          use_taxonomy_term_path: false
+          entity_type: node
+          plugin_id: taxonomy_index_tid_depth_join
+      display_extenders: {  }
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: 1
+    display_options:
+      display_extenders: {  }
+      path: test_argument_taxonomy_index_tid_depth_join
+    cache_metadata:
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - 'user.node_grants:view'
+        - user.permissions
+      cacheable: false
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_depth_join.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_depth_join.yml
new file mode 100644
index 0000000000..d225c6959d
--- /dev/null
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_depth_join.yml
@@ -0,0 +1,178 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
+    - taxonomy
+    - user
+id: test_filter_taxonomy_index_tid_depth_join
+label: test_filter_taxonomy_index_tid_depth_join
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 1
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Filter
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: full
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: '‹ Previous'
+            next: 'Next ›'
+            first: '« First'
+            last: 'Last »'
+          quantity: 9
+      style:
+        type: default
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          uses_fields: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          label: ''
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            trim: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            html: false
+          hide_empty: false
+          empty_zero: false
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exclude: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_alter_empty: true
+          plugin_id: field
+          entity_type: node
+          entity_field: title
+      filters:
+        status:
+          value: '1'
+          table: node_field_data
+          field: status
+          id: status
+          expose:
+            operator: '0'
+          group: 1
+          plugin_id: boolean
+          entity_type: node
+          entity_field: status
+        tid_depth:
+          id: tid_depth
+          table: node_field_data
+          field: term_node_tid_depth
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: or
+          value: { }
+          group: 1
+          exposed: false
+          expose:
+            operator_id: '0'
+            label: ''
+            description: ''
+            use_operator: false
+            operator: ''
+            identifier: ''
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+            reduce: false
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          reduce_duplicates: false
+          type: select
+          limit: true
+          vid: views_testing_tags
+          hierarchy: true
+          depth: -2
+          error_message: true
+          plugin_id: taxonomy_index_tid_depth_join
+      sorts: {  }
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index e1a4d8ccc9..58b510fa8a 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -660,7 +660,7 @@ function views_query_views_alter(AlterableInterface $query) {
   // Replaces substitutions in tables.
   foreach ($tables as $table_name => $table_metadata) {
     foreach ($table_metadata['arguments'] as $replacement_key => $value) {
-      if (isset($substitutions[$value])) {
+      if (is_scalar($value) && isset($substitutions[$value])) {
         $tables[$table_name]['arguments'][$replacement_key] = $substitutions[$value];
       }
     }
