Question: **Goal:**

Add a database index to a 'created' field.

**Given:**

There is a custom entity with a base field `created`.
The field is stored the entity table. 
Field source code of the `created` field:

```
$fields['created'] = BaseFieldDefinition::create('created')
  ->setLabel(t('Created'))
  ->setDescription(t('The time that the entity was created.'))
  ->setDisplayOptions('view', [
    'label' => 'hidden',
    'type' => 'timestamp',
    'weight' => 3,
    'settings' => [
      'date_format' => 'medium',
      'custom_date_format' => '',
      'timezone' => '',
    ],
  ])
  ->setDisplayConfigurable('view', TRUE);

```

**What I researched:**

I have not found a way to add index using the `\Drupal\Core\Field\BaseFieldDefinition()`.

As I understand indexes are defined in a `@FieldType` plugin. The `created` field is implemented via the `\Drupal\Core\Field\Plugin\Field\FieldType\TimestampItem()` plugin and obviously does not have have indexes there.

P.S. I know, that I can write an updatescript to add an index to the table manually.

Answer: 
Currently the only way to do that is to create your own storage\_schema entity handler.

See Node as an example, the annotation:

```
*     "storage_schema" = "Drupal\node\NodeStorageSchema",

```

There you can alter both the schema for a while table, or you can do it for a specific field. NodeStorageSchema does both:

```
  /**
   * {@inheritdoc}
   */
  protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) {
    $schema = parent::getEntitySchema($entity_type, $reset);

    $schema['node_field_data']['indexes'] += array(
      'node__frontpage' => array('promote', 'status', 'sticky', 'created'),
      'node__status_type' => array('status', 'type', 'nid'),
      'node__title_type' => array('title', array('type', 4)),
    );

    return $schema;
  }

```

And below in getSharedTableFieldSchema():

```
if ($table_name == 'node_revision') {
  switch ($field_name) {
    case 'langcode':
      $this->addSharedTableFieldIndex($storage_definition, $schema, TRUE);
      break;

    case 'revision_uid':
      $this->addSharedTableFieldForeignKey($storage_definition, $schema, 'users', 'uid');
      break;
  }
}

```
While the above API approaches are recommended, here's one more raw approach that can be useful for some cases. 

In this case, it adds an SQL index to a base field for the MySQL/MariaDB database engine:

```
/**
 * Add SQL index on published_date base field
 */
function MY_MODULE_update_8010(&$sandbox) {
  // Add index
  // ALTER TABLE $table ADD INDEX $name ($column1, $column2..)
  db_query("ALTER TABLE node_field_data ADD INDEX node_field__published_date (published_date)");
}

```