How do I bulk delete taxonomy terms? I'm looking for a way to delete about 1300 taxonomy terms (of 5250 in total) and their association with nodes.
I firstly thought to delete the content of these tables:


taxonomy_index 
taxonomy_term_data 
taxonomy_ter_field_data    
taxonomy_term_hierarchy       
node__field_tags
node_revision__field_tag


Is this sufficient?
Is there a better way to do it, without Drush, which I cannot install?

EDIT :

I'm trying to do it programmaticaly, but I have an error 

Error: Call to undefined function field_attach_delete() in delete_taxonomy_terms() (line 42 of /var/www/html/d8/delete_tags.php).


Trying to add call to module_load_include() but still get the same error.
I put the file at the root of my Drupal installation (../mydrupal/delete_tags.php).

&lt;?php
error_reporting(E_ALL);
date_default_timezone_set('Europe/Paris');

define('DRUPAL_DIR', $_SERVER["DOCUMENT_ROOT"]); //__DIR__ ); //.'/../drupal');

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

$autoloader = require_once 'autoload.php';
$kernel = new DrupalKernel('prod', $autoloader);
$request = Request::createFromGlobals();
$response = $kernel-&gt;handle($request);
$response-&gt;send();
$kernel-&gt;terminate($request, $response);

/**
 * Deletes taxonomy terms.
 *
 * @param array $tids
 *   Array of taxonomy term IDs.
 */

$tids = [830];

delete_taxonomy_terms($tids);

function delete_taxonomy_terms($tids) {

module_load_include("inc", "field", "field.attach");

  db_delete('taxonomy_term_data')
    -&gt;condition('tid', $tids, 'IN')
    -&gt;execute();
  db_delete('taxonomy_term_hierarchy')
    -&gt;condition('tid', $tids, 'IN')
    -&gt;execute();

  $terms = taxonomy_term_load_multiple($tids);

  foreach ($terms as $term) {
    field_attach_delete('taxonomy_term', $term);
    module_invoke_all('taxonomy_term_delete', $term);
    module_invoke_all('entity_delete', $term, 'taxonomy_term');
  }

  // Reset static cache after all terms deleted.
  taxonomy_terms_static_reset();
}
Before you clean the vocabulary you need to change the taxonomy reference field, to do this you can use this code:

$nids = \Drupal::entityQuery('node')-&gt;condition('type','YOUR_CONTENT_TYPE')-&gt;execute();
$nodes =  \Drupal\node\Entity\Node::loadMultiple($nids);

foreach($nodes as $node) {
  // Change your term here
  $node-&gt;field_YOUR_TAXONOMY_REFERENCE_FIELD-&gt;value = '';
 $node-&gt;save();
}


To clean the vocabulary use this modification of a drush command that you can see in https://github.com/adrian-cid/drush_commands/blob/master/drush_taxonomy.drush.inc

You need to pass an array of vocabularies names to clean.

I use the dpm() function (you need to install Devel) to show the messages, but you can change it if you want.

function taxonomy_vocabulary_clean(array $names) {
  if (!empty($names)) {
    // Check for duplicate ids.
    $test_names = array_unique($names);
    if (count($test_names) != count($names)) {
      dpm('You have duplicate vocabulary names.');
      return;
    }
    //Searching the vocabularies in the site
    $vocabulary_in_db = array_keys(Drupal\taxonomy\Entity\Vocabulary::loadMultiple());
    $vocabulary_non_existent = array_diff($names, $vocabulary_in_db);
    $vocabulary_existent = array_diff($names, $vocabulary_non_existent);

    if (count($vocabulary_existent) == 0) {
      dpm("The desired vocabulary to clean doesn't exists.");
      return;
    }
    if (count($vocabulary_non_existent)) {
      dpm('Non-existent vocabulary:');
      dpm(implode(' ', $vocabulary_non_existent));
    }

    foreach ($vocabulary_existent as $name) {
      $tids = \Drupal::entityQuery('taxonomy_term')
        -&gt;condition('vid', $name)
        -&gt;execute();

      $controller = \Drupal::entityTypeManager()-&gt;getStorage('taxonomy_term');
      $entities = $controller-&gt;loadMultiple($tids);
      $controller-&gt;delete($entities);
    }
    dpm('Vocabulary cleaned:');
    dpm(implode(' ', $vocabulary_existent));
  }
  else {
    dpm('You must enter at least one vocabulary name.');
  }
}


Using the function:

taxonomy_vocabulary_clean(['tags', 'my_vocabulary_machine_name']);


The Drupal 7 code:

function taxonomy_vocabulary_clean(array $names) {
  if (!empty($names)) {
    // Check for duplicate ids.
    $test_names = array_unique($names);
    if (count($test_names) != count($names)) {
      dpm('You have duplicate vocabulary names.'));
      return;
    }
    //Searching the vocabularies in the site
    $vocabulary_in_db = array_column(taxonomy_get_vocabularies(), 'machine_name');
    $vocabulary_non_existent = array_diff($names, $vocabulary_in_db);
    $vocabulary_existent = array_diff($names, $vocabulary_non_existent);

    if(count($vocabulary_existent) == 0) {
      dpm("The desired vocabulary to clean doesn't exists.");
      return;
    }
    if(count($vocabulary_non_existent)) {
      dpm('Non-existent vocabulary:');
      dpm(implode(' ', $vocabulary_non_existent));
    }

    foreach ($vocabulary_existent as $name) {
      $vid = taxonomy_vocabulary_machine_name_load($name)-&gt;vid;
      foreach(taxonomy_get_tree($vid) as $term) {
        taxonomy_term_delete($term-&gt;tid);
      }
    }
    dpm('Vocabulary cleaned:');
    dpm(implode(' ', $vocabulary_existent));
  }
  else {
    dpm('You must enter at least one vocabulary name.');
  }
}