Bicycle speedometer

There's a delay(100) in the loop. This means your sensor is checked only once every 100 ms. That's plenty of time to miss a rotation. And indeed you need to detect the change as pointed out above.

Try this:

bool tick = false;
uint32_t detectedTime = 0;
uint16_t ledTime = 300;
void loop() {
  if(digitalRead(switchPin) == LOW && tick == false){
    times = times + 1;
    tick = true;
    detectedTime = millis();
    Serial.print("Wheel turn times: ");
    Serial.println(times);
  }
  if (millis() - detectedTime < ledTime)
    ditigalWrite(ledPin, LOW)
  else {
    digitalWrite(ledPin, HIGH);
  }

  /* Check the relay status */
  if(times==3) {
    digitalWrite(relay1, LOW);
  }else if(times==8) {
    digitalWrite(relay2, LOW);
  }
  
}

Upon tick detection the flag is set, the number of rotations so far is printed, a timer is started, and the LED lights up for 300 ms.
No delay() in the loop() allows your sensor to be checked much much more frequent. That delay() is probably the killer, together with your Serial.print() statement which also takes time.