From what I know, you are comparing different things (even if their names are similar and this could be misleading).
As you correctly wrote, the QgsSpatialIndex() class is useful for finding nearest objects. The following text is an excerpt from the QGIS Documentation (the [...] and the bold style are added by me for the sake of clearness):
Spatial indexes can dramatically improve the performance of your code
if you need to do frequent queries to a vector layer. [...] This can
be a very time consuming task, especially if it needs to be repeated
for several locations. If a spatial index exists for the layer, the
operation is much more effective.
Spatial indexes are not created by default for a QGIS vector layer,
but you can create them easily. This is what you have to do:
QgsSpatialIndex() class is only used temporarily and improves the performance of querying a shapefile.
Instead, a Spatial Index improves the performance of drawing a shapefile and it is generally stored on disk. The following text is an excerpt from the QGIS Documentation (the bold style is added by me for the sake of clearness):
To improve the performance of drawing a shapefile, you can create a
spatial index. A spatial index will improve the speed of both
zooming and panning. Spatial indexes used by QGIS have a
Use these steps to create the index:
- Load a shapefile.
- Open the
Layer Properties dialog by double-clicking on the shapefile name in the legend or by right-clicking and choosing
Properties from the popup menu.
- In the tab
General click the
[Create Spatial Index] button.
Using PyQGIS, a spatial index would be created using the createSpatialIndex() module from the QgsVectorDataProvider class:
provider = layer.dataProvider()
index = provider.createSpatialIndex()
This will create a spatial index on the datasource and the
.qix file in the same folder where the original shapefile is stored.
With these premises, I try to add something more to the answer in the case of dealing with memory layers instead of persistent shapefiles (the following needs to be intended as a personal opinion since I wasn't able to verify it).
I think that the following text, reported in the QGIS Documentation (the [...] are added by me for the sake of clearness):
The memory provider also supports spatial indexing, which is enabled
by calling the provider’s
createSpatialIndex() function. Once the
spatial index is created you will be able to iterate over features
within smaller regions faster (since it’s not necessary to traverse
all the features, only those in specified rectangle).
A memory provider is created by passing "memory" as the provider
string to the QgsVectorLayer constructor.
The URI can also specify the coordinate reference system, fields, and
indexing of the memory provider in the URI. The syntax is:
`index=yes` (Specifies that the provider will use a spatial index)
refers to a Spatial Index and not to the
QgsSpatialIndex() class, so it is only used for improving the performance of drawing the layer and this justifies why a
QgsSpatialIndex() class is often called when a query on many features is needed.