diff --git a/core/Db/Schema/Mysql.php b/core/Db/Schema/Mysql.php
index 43a42f167d1adc256224d030ab5b244ca37567bf..45ff75b68517fbe78264487b3b9a0fa8fbeade90 100644
--- a/core/Db/Schema/Mysql.php
+++ b/core/Db/Schema/Mysql.php
@@ -341,12 +341,9 @@ class Mysql implements SchemaInterface
             || $forceReload === true
         ) {
             $db = Db::get();
-            $prefixTables = $this->getTablePrefix();
+            $prefixTables = $this->getTablePrefixEscaped();
 
-            // '_' matches any character; force it to be literal
-            $prefixTables = str_replace('_', '\_', $prefixTables);
-
-            $allTables = $db->fetchCol("SHOW TABLES LIKE '" . $prefixTables . "%'");
+            $allTables = $this->getAllExistingTables($prefixTables);
 
             // all the tables to be installed
             $allMyTables = $this->getTablesNames();
@@ -461,8 +458,8 @@ class Mysql implements SchemaInterface
      */
     public function truncateAllTables()
     {
-        $tablesAlreadyInstalled = $this->getTablesInstalled($forceReload = true);
-        foreach ($tablesAlreadyInstalled as $table) {
+        $tables = $this->getAllExistingTables();
+        foreach ($tables as $table) {
             Db::query("TRUNCATE `$table`");
         }
     }
@@ -489,4 +486,21 @@ class Mysql implements SchemaInterface
 
         return $dbName;
     }
+
+    private function getAllExistingTables($prefixTables = false)
+    {
+        if (empty($prefixTables)) {
+            $prefixTables = $this->getTablePrefixEscaped();
+        }
+
+        return Db::get()->fetchCol("SHOW TABLES LIKE '" . $prefixTables . "%'");
+    }
+
+    private function getTablePrefixEscaped()
+    {
+        $prefixTables = $this->getTablePrefix();
+        // '_' matches any character; force it to be literal
+        $prefixTables = str_replace('_', '\_', $prefixTables);
+        return $prefixTables;
+    }
 }
diff --git a/plugins/CustomVariables/tests/ModelTest.php b/plugins/CustomVariables/tests/ModelTest.php
index bfca81c777c003f20bb43b45b6ef79fc3c253a95..3ed82f552a734800d03505760f3a87c5d9cf7deb 100644
--- a/plugins/CustomVariables/tests/ModelTest.php
+++ b/plugins/CustomVariables/tests/ModelTest.php
@@ -7,16 +7,36 @@
  */
 
 namespace Piwik\Plugins\CustomVariables\tests;
+use Piwik\Common;
 use Piwik\Db;
+use Piwik\DbHelper;
 use Piwik\Plugins\CustomVariables\Model;
 
 /**
  * @group CustomVariables
  * @group ModelTest
  * @group Database
+ * @group CustomVariables_ModelTest
  */
 class ModelTest extends \DatabaseTestCase
 {
+    private static $cvarScopes = array('log_link_visit_action', 'log_visit', 'log_conversion');
+
+    public function setUp()
+    {
+        // do not call parent::setUp() since it expects database to be created,
+        // but DB for this test is removed in tearDown
+
+        self::$fixture->performSetUp();
+    }
+
+    public function tearDown()
+    {
+        parent::tearDown();
+
+        self::$fixture->performTearDown();
+    }
+
     /**
      * @expectedException \Exception
      */
@@ -35,7 +55,7 @@ class ModelTest extends \DatabaseTestCase
 
     public function testGetAllScopes()
     {
-        $this->assertEquals(array('log_link_visit_action', 'log_visit', 'log_conversion'), Model::getScopes());
+        $this->assertEquals(self::$cvarScopes, Model::getScopes());
     }
 
     public function test_Install_Uninstall()
diff --git a/plugins/Goals/tests/APITest.php b/plugins/Goals/tests/APITest.php
index 0f393385d953cb6ed5ed7029e53bc3249ba70792..3263bc4972a78dd9a99bea28260d4482907d9956 100644
--- a/plugins/Goals/tests/APITest.php
+++ b/plugins/Goals/tests/APITest.php
@@ -8,6 +8,7 @@
 
 namespace Piwik\Plugins\Goals\tests;
 use Piwik\Access;
+use Piwik\Piwik;
 use Piwik\Plugins\Goals\API;
 use Piwik\Tests\Fixture;
 
@@ -31,6 +32,9 @@ class APITest extends \DatabaseTestCase
         parent::setUp();
         $this->api = API::getInstance();
 
+        Fixture::createAccessInstance();
+        Piwik::setUserHasSuperUserAccess();
+
         Fixture::createWebsite('2014-01-01 00:00:00');
         Fixture::createWebsite('2014-01-01 00:00:00');
     }
diff --git a/tests/PHPUnit/DatabaseTestCase.php b/tests/PHPUnit/DatabaseTestCase.php
index ef247e0f1e86e8ada54e3b9d14e681d9e5ba8c9d..715571eba45848b36824b933d159a5b95837e422 100644
--- a/tests/PHPUnit/DatabaseTestCase.php
+++ b/tests/PHPUnit/DatabaseTestCase.php
@@ -5,8 +5,10 @@
  * @link http://piwik.org
  * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  */
+use Piwik\Config;
 use Piwik\Db;
 use Piwik\Tests\Fixture;
+use Piwik\Tests\IntegrationTestCase;
 
 /**
  * Tests extending DatabaseTestCase are much slower to run: the setUp will
@@ -16,12 +18,48 @@ use Piwik\Tests\Fixture;
  * then test it.
  *
  */
-class DatabaseTestCase extends PHPUnit_Framework_TestCase
+class DatabaseTestCase extends IntegrationTestCase
 {
     /**
      * @var Fixture
      */
-    protected $fixture = null;
+    public static $fixture;
+    public static $tableData;
+
+    /**
+     * Implementation details:
+     *
+     * To increase speed of tests, database setup is done once in setUpBeforeClass.
+     * Afterwards, the content of the tables is stored in a static class variable,
+     * self::$tableData. Before each individual test, the database tables are
+     * truncated and the data in self::$tableData is restored.
+     *
+     * If your test modifies table columns, you will need to recreate the database
+     * completely. This can be accomplished by:
+     *
+     *     public function setUp()
+     *     {
+     *         self::$fixture->performSetUp();
+     *     }
+     *
+     *     public function tearDown()
+     *     {
+     *         parent::tearDown();
+     *         self::$fixture->performTearDown();
+     *     }
+     */
+    public static function setUpBeforeClass()
+    {
+        static::configureFixture(static::$fixture);
+        parent::setUpBeforeClass();
+
+        self::$tableData = self::getDbTablesWithData();
+    }
+
+    public static function tearDownAfterClass()
+    {
+        self::$tableData = array();
+    }
 
     /**
      * Setup the database and create the base tables for all tests
@@ -30,9 +68,11 @@ class DatabaseTestCase extends PHPUnit_Framework_TestCase
     {
         parent::setUp();
 
-        $this->fixture = new Fixture();
-        $this->configureFixture();
-        $this->fixture->performSetUp();
+        Config::getInstance()->setTestEnvironment();
+
+        if (!empty(self::$tableData)) {
+            self::restoreDbTables(self::$tableData);
+        }
     }
 
     /**
@@ -40,14 +80,17 @@ class DatabaseTestCase extends PHPUnit_Framework_TestCase
      */
     public function tearDown()
     {
+        self::$fixture->clearInMemoryCaches();
+
         parent::tearDown();
-        $this->fixture->performTearDown();
     }
 
-    protected function configureFixture()
+    protected static function configureFixture($fixture)
     {
-        $this->fixture->loadTranslations = false;
-        $this->fixture->createSuperUser = false;
-        $this->fixture->configureComponents = false;
+        $fixture->loadTranslations = false;
+        $fixture->createSuperUser = false;
+        $fixture->configureComponents = false;
     }
 }
+
+DatabaseTestCase::$fixture = new Fixture();
\ No newline at end of file
diff --git a/tests/PHPUnit/Fixture.php b/tests/PHPUnit/Fixture.php
index c50931016c73676effb6aa761ef6cb614a4f6d59..cc72b8498d836ea6334474e833b77aa15c5a7024 100644
--- a/tests/PHPUnit/Fixture.php
+++ b/tests/PHPUnit/Fixture.php
@@ -275,6 +275,11 @@ class Fixture extends PHPUnit_Framework_Assert
             $this->dropDatabase();
         }
 
+        $this->clearInMemoryCaches();
+    }
+
+    public function clearInMemoryCaches()
+    {
         DataTableManager::getInstance()->deleteAll();
         Option::clearCache();
         Site::clearCache();
@@ -291,7 +296,7 @@ class Fixture extends PHPUnit_Framework_Assert
         Config::unsetInstance();
 
         \Piwik\Config::getInstance()->Plugins; // make sure Plugins exists in a config object for next tests that use Plugin\Manager
-                                               // since Plugin\Manager uses getFromGlobalConfig which doesn't init the config object
+        // since Plugin\Manager uses getFromGlobalConfig which doesn't init the config object
     }
 
     public static function loadAllPlugins($testEnvironment = null, $testCaseClass = false, $extraPluginsToLoad = array())
diff --git a/tests/PHPUnit/Integration/Core/AccessTest.php b/tests/PHPUnit/Integration/Core/AccessTest.php
index cba36a9f93a5abccb3feee5abe0b2e4d818aeed1..ec1eb9bd29800c9c4fb7ffbff567a4ac522a3bb9 100644
--- a/tests/PHPUnit/Integration/Core/AccessTest.php
+++ b/tests/PHPUnit/Integration/Core/AccessTest.php
@@ -11,7 +11,6 @@ use Piwik\AuthResult;
 /**
  * Class Core_AccessTest
  *
- * @group Core_AccessTest
  * @group Core
  */
 class Core_AccessTest extends DatabaseTestCase
diff --git a/tests/PHPUnit/Integration/Core/CronArchive/SharedSiteIdsTest.php b/tests/PHPUnit/Integration/Core/CronArchive/SharedSiteIdsTest.php
index 5183177aa93ced8ee0987afbc95911d9c6704a06..eca1d85aeab1594b603a1037fe70744fa674f8e5 100644
--- a/tests/PHPUnit/Integration/Core/CronArchive/SharedSiteIdsTest.php
+++ b/tests/PHPUnit/Integration/Core/CronArchive/SharedSiteIdsTest.php
@@ -10,6 +10,7 @@ use Piwik\CronArchive\SharedSiteIds;
 
 /**
  * @group Core
+ * @group SharedSiteIdsTest
  */
 class SharedSiteIdsTest extends DatabaseTestCase
 {
@@ -21,7 +22,6 @@ class SharedSiteIdsTest extends DatabaseTestCase
     public function setUp()
     {
         parent::setUp();
-        $this->fixture->performSetUp(true);
 
         $this->sharedSiteIds = new SharedSiteIds(array(1,2,5,9));
     }
diff --git a/tests/PHPUnit/Integration/Core/LogTest.php b/tests/PHPUnit/Integration/Core/LogTest.php
index f7d35e451b334d8e1430ae38aa1f3214515697b9..a3923183ae4a6f0d11e51e6a6feb60c44a93d8ba 100644
--- a/tests/PHPUnit/Integration/Core/LogTest.php
+++ b/tests/PHPUnit/Integration/Core/LogTest.php
@@ -31,9 +31,9 @@ class Core_LogTest extends DatabaseTestCase
         'screen' => 'dummy error message<br />
  <br />
  --&gt; To temporarily debug this error further, set const PIWIK_PRINT_ERROR_BACKTRACE=true; in index.php',
-        'file' => '[Core_LogTest] LogTest.php(161): dummy error message
+        'file' => '[Core_LogTest] LogTest.php(165): dummy error message
   dummy backtrace',
-        'database' => '[Core_LogTest] LogTest.php(161): dummy error message
+        'database' => '[Core_LogTest] LogTest.php(165): dummy error message
 dummy backtrace'
     );
 
@@ -55,6 +55,8 @@ dummy backtrace'
 
     public static function setUpBeforeClass()
     {
+        parent::setUpBeforeClass();
+
         Error::setErrorHandler();
         ExceptionHandler::setUp();
     }
@@ -63,6 +65,8 @@ dummy backtrace'
     {
         restore_error_handler();
         restore_exception_handler();
+
+        parent::tearDownAfterClass();
     }
 
     public function setUp()
diff --git a/tests/PHPUnit/Integration/Core/OptionTest.php b/tests/PHPUnit/Integration/Core/OptionTest.php
index c926e1c808140962907f7928d863dc615ba3cb71..41a12df3fd6e368069b4443795032174f05fd7b5 100644
--- a/tests/PHPUnit/Integration/Core/OptionTest.php
+++ b/tests/PHPUnit/Integration/Core/OptionTest.php
@@ -13,6 +13,7 @@ use Piwik\Option;
  * Class Core_OptionTest
  *
  * @group Core
+ * @group Core_OptionTest
  */
 class Core_OptionTest extends DatabaseTestCase
 {
diff --git a/tests/PHPUnit/Integration/Core/SegmentTest.php b/tests/PHPUnit/Integration/Core/SegmentTest.php
index ce7a0c363f82350689cf4b0aa3c9100b73d8583f..3fddab94b27907341d57224752fb1afd991added 100644
--- a/tests/PHPUnit/Integration/Core/SegmentTest.php
+++ b/tests/PHPUnit/Integration/Core/SegmentTest.php
@@ -8,8 +8,10 @@
 use Piwik\Access;
 use Piwik\Common;
 use Piwik\Segment;
-use Piwik\Tests\Fixture;
 
+/**
+ * @group SegmentTest
+ */
 class SegmentTest extends DatabaseTestCase
 {
     public function setUp()
@@ -20,14 +22,11 @@ class SegmentTest extends DatabaseTestCase
         $pseudoMockAccess = new FakeAccess;
         FakeAccess::$superUser = true;
         Access::setSingletonInstance($pseudoMockAccess);
-
-        Fixture::loadAllPlugins();
     }
 
     public function tearDown()
     {
         parent::tearDown();
-        Fixture::unloadAllPlugins();
     }
 
     protected function _filterWhitsSpaces($valueToFilter)
diff --git a/tests/PHPUnit/Integration/Core/TrackerTest.php b/tests/PHPUnit/Integration/Core/TrackerTest.php
index 12886a6778dd4017cf530e9945ab87d8732c06b3..a5eb8cbcb8bbc00b3af6b218784277eae91ba2e3 100644
--- a/tests/PHPUnit/Integration/Core/TrackerTest.php
+++ b/tests/PHPUnit/Integration/Core/TrackerTest.php
@@ -19,9 +19,9 @@ class Core_TrackerTest extends DatabaseTestCase
         Fixture::createWebsite('2014-02-04');
     }
 
-    protected function configureFixture()
+    protected static function configureFixture($fixture)
     {
-        $this->fixture->createSuperUser = true;
+        $fixture->createSuperUser = true;
     }
 
     /**
diff --git a/tests/PHPUnit/IntegrationTestCase.php b/tests/PHPUnit/IntegrationTestCase.php
index 89e5612a90cd01811744b1f3c8b67adfe0a9438f..d5d78128a4552d64a401f45533c00e87f4bc11fd 100755
--- a/tests/PHPUnit/IntegrationTestCase.php
+++ b/tests/PHPUnit/IntegrationTestCase.php
@@ -518,7 +518,6 @@ abstract class IntegrationTestCase extends PHPUnit_Framework_TestCase
      */
     protected static function restoreDbTables($tables)
     {
-        // truncate existing tables
         DbHelper::truncateAllTables();
 
         // insert data
diff --git a/tests/PHPUnit/bootstrap.php b/tests/PHPUnit/bootstrap.php
index dc16386563641a42d73c8d9a8101a5317298c05c..2fd701a0e87e9728e0bed7abf37f76788ad6dba3 100644
--- a/tests/PHPUnit/bootstrap.php
+++ b/tests/PHPUnit/bootstrap.php
@@ -34,8 +34,9 @@ require_once file_exists(PIWIK_INCLUDE_PATH . '/vendor/autoload.php')
 require_once PIWIK_INCLUDE_PATH . '/libs/upgradephp/upgrade.php';
 require_once PIWIK_INCLUDE_PATH . '/core/testMinimumPhpVersion.php';
 require_once PIWIK_INCLUDE_PATH . '/core/FrontController.php';
-require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/DatabaseTestCase.php';
+require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/Fixture.php';
 require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/IntegrationTestCase.php';
+require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/DatabaseTestCase.php';
 require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/ConsoleCommandTestCase.php';
 require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/FakeAccess.php';
 require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/MockPiwikOption.php';
@@ -49,8 +50,6 @@ if (getenv('PIWIK_USE_XHPROF') == 1) {
 }
 
 // require test fixtures
-require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/Fixture.php';
-
 $fixturesToLoad = array(
     '/tests/PHPUnit/Fixtures/*.php',
     '/tests/PHPUnit/UI/Fixtures/*.php',